دليل تنفيذ مصادقة خادم MCP: باستخدام المواصفة الأحدث
يقدم نقاط تنفيذ رئيسية لتوافق مصادقة خادم MCP مع مواصفة 2025-06-18.
منذ بضعة أيام (18 يونيو 2025)، أصدرت فريق MCP (بروتوكول سياق النماذج) أحدث نسخة من مواصفة MCP (2025-06-18). يتضمن هذا التحديث تغييرًا رئيسيًا في مواصفة المصادقة. لن تقوم خوادم MCP بعد الآن بإصدار رموز الوصول كخادم تفويض (Authorization Server). بدلاً من ذلك، ستستهلك رموز الوصول وتوفر الموارد باعتبارها خادم موارد.
كأحد القائمين على صيانة MCP Auth (مكتبة مصادقة خادم MCP قابلة للتوصيل الفوري)، قمت بتنفيذ دعم لأحدث مواصفة مصادقة MCP في هذا المشروع. استنادًا إلى خبرتي العملية، سأوضح لك كيفية تنفيذ ميزات المصادقة لخادم MCP الخاص بك بما يتوافق مع أحدث مواصفة.
سيساعدك هذا المقال على:
- فهم كيفية عمل مصادقة MCP بموجب المواصفة الجديدة
- توضيح ما يجب على خوادم MCP تنفيذه بصفتها خوادم موارد حسب متطلبات المواصفة
- تقديم إرشادات لتنفيذ دعم المصادقة بما يتوافق مع أحدث مواصفة لخادم MCP
- تحديد النقاط التي قد يتم تجاهلها والمشكلات الأمنية عند تنفيذ مواصفة المصادقة
يرجى ملاحظة أن هذا المقال:
- يفترض أن القراء لديهم معرفة أساسية بـ JWT (رمز الويب JSON). لن يغطي المقال هيكل JWT، التحقق من التوقيع، وغيرها من المفاهيم الأساسية بالتفصيل. لمزيد من التفاصيل، راجع ويكي المصادقة - JWT
- لا يقدم مقدمة متعمقة حول مختلف RFCs التي تعتمد عليها مواصفة مصادقة MCP. بل يقدم فقط تطبيقات تتوافق مع متطلبات هذه RFCs
- لا يغطي تفاصيل تنفيذ العميل MCP والتفويض والتفاعل بينهما. عادةً ما يتم تنفيذ هذه من قبل عملاء LLM ومزودي خوادم التفويض الداعمين لـ MCP حسب المواصفات. مطورو خوادم MCP ليس عليهم ولا يمكنهم التدخل في هذه التنفيذات. لمزيد من التفاصيل، راجع عميل OAuth وخادم التفويض
- جميع رموز الوصول المذكورة في المقال يفترض أن تكون بصيغة JWT، وهي الشكل الأكثر انتشارًا في السوق. الأشكال الأخرى من الرموز يجب استخدامها طبقًا لتوثيقات مزود خادم التفويض المعني.
كيف تعمل مصادقة MCP؟
وفقًا لأحدث مواصفة مصادقة MCP، يُعرض تدفق مصادقة MCP في المخطط التالي:
-
يطلب عميل MCP الموارد من خادم MCP عند
https://github-tools.com
. بما أن المستخدم لم يسجل دخوله بعد، لا يحتوي ترويسة التفويض في هذا الطلب على رمز وصول يمثل المستخدم. -
خادم MCP لا يمكنه الحصول على رمز وصول من ترويسة تفويض طلب العميل. يرجع خطأ HTTP 401. يتضمن هذا الرد ترويسة WWW-Authenticate، والتي تحتوي على رابط بيانات مورد الخادم (قيمة حقل
resource_metadata
). -
يستخرج عميل MCP قيمة
resource_metadata
من ترويسة WWW-Authenticate المرتجعة (مثلاً:https://github-tools.com/.well-known/oauth-protected-resource
). ثم يطلب بيانات الموارد التي يوفرها MCP كخادم موارد من هذا العنوان. تتضمن هذه البيانات معلومات مثلauthorization_servers
وscopes_supported
، لمساعدة العميل على معرفة كيفية الحصول على رمز وصول للوصول إلى الخادم، ومن أي خادم تفويض يحصل على رمز بصلاحيات معينة.
4-8. يطلب عميل MCP بيانات خادم التفويض بناءً على رابط البيانات الذي تم الحصول عليه من بيانات الموارد. ثم يجري عملية تفويض OAuth 2.1 مع خادم التفويض ويحصل على رمز وصول بعد إكمال التفويض.
-
يحمل عميل MCP رمز الوصول الذي حصل عليه من خادم التفويض ويعيد طلب المورد من خادم MCP.
-
يرجع خادم MCP المورد المطلوب بعد التحقق من صحة الرمز. بعد ذلك، يستمر التواصل بين العميل والخادم باستخد ام الرمز الصالح.
سوف نشرح خطوة بخطوة كيفية تنفيذ آلية مصادقة خادم MCP بناءً على هذا التدفق.
التعامل مع الطلبات غير المصرح بها: إرجاع خطأ 401 وترويسة WWW-Authenticate
كما هو موضح أعلاه، عند إرسال العميل طلبًا بدون رمز وصول إلى خادم MCP، يقوم الخادم بإرجاع خطأ HTTP 401 Unauthorized مع ترويسة WWW-Authenticate
تحتوي على رابط بيانات الموارد.
وفقًا لـ معالجة أخطاء مواصفة مصادقة MCP، بالإضافة إلى طلبات العملاء بدون رمز وصول، إذا تلقى الخادم رمز وصول غير صالح، يجب أيضًا إرجاع 401 مع ترويسة WWW-Authenticate
.
بعد معرفة متى نعيد خطأ 401، كيف نبني ترويسة WWW-Authenticate
المرجعة؟
وفقًا لـ RFC9728 Section 5.1، يجب أن تتضمن ترويسة WWW-Authenticate
معلمة resource_metadata
تشير إلى رابط بيانات المورد المحمي.
الصيغة الأساسية كالتالي:
هنا، Bearer
هو نظام المصادقة، مما يدل على الحاجة إلى رمز حامل للوصول إلى موارد محمية بـ OAuth 2.0 (انظر: توثيقات MDN). وقيمة معلمة resource_metadata
التي تليها هي الرابط الكامل لنقطة نهاية بيانات المورد التي يوفرها خادم MCP الخاص بك.
تنفيذ الكود الفعلي سيكون:
عندما يستلم عميل MCP هذا الخطأ 401، سيصل إلى بيانات موارد الخادم من خلال قيمة resource_metadata
في ترويسة WWW-Authenticate
. ثم، بناءً على المعلومات التي توفرها بيانات الموارد، سيبدأ طلب تفويض إلى خادم التفويض المحدد للحصول على رمز وصول يمكن استخدامه للوصول إلى الخادم.
الآن عرفنا متى نعيد خطأ 401 وأننا بحاجة لإرجاع رابط بيانات الموارد. لكن لا نعلم كيف نبني هذا الرابط وما الذي يحتويه. سنشرح ذلك تاليًا.
تنفيذ آلية اكتشاف بيانات الموارد
بناءً على تدفق مصادقة MCP، بعد تلقي العميل خطأ 401، يطلب فورًا بيانات الموارد من الخادم. لذا يجب على خادم MCP بصفته خادم موارد تنفيذ آلية اكتشاف بيانات الموارد.
تحديد مسار رابط نقطة نهاية البيانات
في نظام OAuth، نستخدم الروابط لتعريف عناوين الموارد. يسمى هذا العنوان "مؤشر المورد - resource indicator". حسب مواصفة RFC9728، يجب أن تُستضاف بيانات الموارد ضمن مسار /.well-known
محدد.
إذا كان خادم MCP الخاص بك (مثل https://github-tools.com
) يقدم خدمة واحدة فقط، يجب أن تكون نقطة نهاية البيانات:
إذا كنت تقدم عدة خدمات مختلفة على نفس المضيف، يجب أن يكون لكل خدمة نقطة نهاية بيانات مستقلة. مثلاً، المنصة https://api.acme-corp.com
تقدم الخدمات التالية:
https://api.acme-corp.com/github
- خدمة تكامل GitHubhttps://api.acme-corp.com/slack
- خدمة تكامل Slackhttps://api.acme-corp.com/database
- خدمة قاعدة البيانات
وينبغي أن تكون نقاط نهاية البيانات:
https://api.acme-corp.com/.well-known/oauth-protected-resource/github
https://api.acme-corp.com/.well-known/oauth-protected-resource/slack
https://api.acme-corp.com/.well-known/oauth-protected-resource/database
ميزة هذا التصميم أنه يمكن لكل خدمة أن يكون لها صلاحيات تفويض وخوادم تفويض مختلفة. مثلاً:
- خدمة GitHub تستخدم خادم تفويض GitHub وتحتاج صلاحيات
github:read
،github:write
- خدمة Slack تستخدم خادم تفويض Slack وتحتاج صلاحيات
slack:channels:read
،slack:messages:write
- خدمة القاعدة تستخدم خادم تفويض داخلي وتحتاج صلاحية
db:query
من هذه الحالات نستنتج أن روابط نقاط نهاية البيانات تتبع النمط:
ويمكننا الحصول على رابط نقطة نهاية بيانات المورد بهذه الطريقة:
بناء استجابة بيانات الموارد
بعد تحديد المسار، يجب أن تُرجع هذه النقطة بيانات تعريف بصيغة JSON تتوافق مع RFC9728.
في التطبيق العملي، نركّز على أربعة حقول أساسية:
أولاً: الحقل resource
، وهو معرف المورد ويجب أن يتطابق مع العنوان الذي يريد عميل MCP الوصول إليه.
ثانياً: الحقل authorization_servers
، وهو مصفوفة تُحدد خوادم التفويض التي يجب على العميل طلب رموز وصول منها. حسب مواصفة OAuth 2.0 Protected Resource Metadata (RFC 9728) هذا الحقل اختياري. لكن في مواصفة MCP هو إلزامي لأن العميل يحتاج لمعرفته للتمكن من بدء عملية OAuth. بدونه لا يمكنه إكمال التدفق.
ثم الحقل scopes_supported
، ويحدد كافة صلاحيات الوصول المدعومة.
وأخيرًا، الحقل bearer_methods_supported
، ويخبر العميل ما هي الطرق المدعومة لإرسال رموز الوصول عادة نضبطه على ["header"]
, أي بعد الحصول على رمز الدخول من خادم التفويض، يجب على العميل إرساله في ترويسة Authorization.
مثال عملي. لنُهيئ بيانات المورد لـ https://github-tools.com
:
تُعلِم هذه التهيئة عميل MCP عدة معلومات مهمة: أنه يريد الوصول إلى المورد https://github-tools.com
، ويحتاج لطلب رمز من https://auth.github-tools.com
ويمكنه طلب صلاحيات مثل github:read
وgithub:write
وrepo:admin
، ويجب تمرير الرمز في ترويسة Authorization.
في أغلب الحالات، إعداد هذه الحقول الأربعة يكفي ليستطيع العميل العمل. إذا احتجت مزيدًا من التعقيد راجع حقل مواصفة RFC9728 بالكامل.
تحقق من رموز الوصول
بعد أن يحصل عميل MCP على رمز من خادم التفويض، ينقله للوصول إلى الخادم.
في التطبيق العملي يجب على خوادم MCP مراعاة ما يلي عند التحقق من الرموز:
- عند التحقق الأساسي من الرمز، اعتمد على تهيئة الخادم وليس على معلومات الخادم المحمولة في الرمز.
- تحقق أن الجهة المستهدفة للرمز audience هي الخادم نفسه، بمعنى أن الرمز صدر فعليًا للوصول لموارد الخادم نفسه.
- تعامل مع عمليات التحقق من الصلاحيات (النطاقات) بشكل صحيح
استخدم تهيئة خادم MCP للتحقق
عندما يستلم الخادم رمز وصول، لأن الرمز نفسه يحمل معلومات عن الخادم (issuer)، قد يقوم بعض المطورين بالحصول فورًا على بيانات التحقق استنادًا للـ issuer
الموجود في الرمز فقط. خاصة إذا كان هناك عدة خوادم للتفويض معرفين، كما في المثال:
هنا قد يقوم المطور باستخراج issuer
مباشرة من رمز غير موثق ويبحث عن بيانات خادم التفويض المطابق ويستخدمها للتحقق. إذا كان المهاجم قادرًا على إنشاء خادم تفويض مزيف وإصدار رمز غير حقيقي لـ MCP، وتم الاعتماد على issuer
من الرمز بدون تطابق مع التهيئة في الخادم، قد ينجح التحقق من رمز غير صالح.
إذًا الطريقة الصحيحة:
- إذا كان هناك خادم واحد للتفويض: تحقق الرمز مباشرة بناءً على تهيئة الخادم الخاصة
- إذا كان هناك عدة خوادم تفويض: استخرج
issuer
من الرمز غير الموثق، وابحث عن مطابق له ضمن خوادم التفويض المعرفين. إذا لم يوجد خادم مطابق، ارفض الرمز
وأيضًا عند التحقق، تأكد من صحة اسم خادم التفويض (issuer).
باستخدام مكتبة jose للتحقق من JWT:
تحقق من audience
تنص ربط والتحقق من audience في مواصفة MCP على أنه عند طلب رمز من خادم التفويض، يجب على العميل تحديد المورد الذي سيستخدم الرمز عليه. كما يجب على خادم MCP التحقق من أن audience في الرمز مطابق لمعرف المورد الخاص به.
هذا مقتبس من معيار Resource Indicators for OAuth 2.0 (RFC 8707). باختصار آلية العمل كالتالي:
-
عند طلب العميل الرمز، يحدد البرنامج سلسلة
resource
في الطلب، ليخبر خادم التفويض للمورد المقصود (مثلاً:https://github-tools.com
) -
عند إصدار الرمز، يربط خادم التفويض المورد بالرمز بأن يكتبه في الحقل audience للـ JWT
-
عند التحقق يستخلص الخادم audience ويتأكد أنها مطابقه لمعرفه نفسه
مثال عملي بمعرف المورد https://github-tools.com
:
هذا التحقق جوهري لأمن النظام، إذ يدعم منع إساءة استخدام الرموز. بدون هذه الخطوة قد يستقبل الخادم رموزًا صالحة ولكنها مخصصة لخدمات أخرى.
التحقق من الصلاحيات (النطاقات)
تدير بعض خوادم MCP الصلاحيات بناءً على المستخدم وموارد متعلقة بهم.
بعد صحة الرمز ينبغي التأكد أن الرمز يتضمن الصلاحيات المطلوبة، ذلك بفحص أن حقل scope
ضمن الرمز يحتوي الصلاحية المطلوبة:
حسب مواصفة مصادقة MCP، عندما لا يمتلك الرمز الصلاحية الكافية، يجب إرجاع 403 Forbidden.
الخلاصة
مع شرح هذا المقال، ينبغي أن تكون لديك القدرة على تنفيذ ميزات مصادقة تمتثل لأحدث مواصفات خادم MCP. لا تنس النقاط التالية: تحقق من الرموز بأمان، ضبط بيانات الموارد بدقة، تحقق من audience بدقة.
إذا كنت تبني خادم MCP جرب مكتبة MCP Auth. فقد نفذت بالفعل كل ما ناقشناه هنا وتساعدك على الدمج السريع لدعم المصادقة.
لا تتردد في مناقشة أي استفسار عبر GitHub. لنعمل معًا لدفع منظومة MCP إلى الأمام.