الدليل الكامل لتكامل خادم OIDC في مشروعك
تعلم أفضل الممارسات لتكامل خادم OIDC (ربط الهوية) في مشروعك وفهم كيفية تفاعل المكونات مع بعضها البعض على الساحة.
قد تصادف موقفًا تحتاج فيه إلى نظام مصادقة وتفويض مركزي، المعروف أيضًا بإدارة الوصول للهوية (IAM) أو مزود الهوية (IdP). أحيانًا يتم إضافة كلمة لتحديد العمل، مثل IAM للعملاء وIAM للموظفين.
دعونا نترك هذه الأسماء المبهجة جانبًا للحظة. الحاجة إلى IAM قد تنشأ لأن تطبيقك ينمو، أو تخطط لتسليم العمل الشاق لمورِّد من البداية. على أية حال، أنت تصل إلى نقطة تحتاج فيها إلى تقديم نظام هوية إلى مشروعك.
بالنظر إلى شعبية OAuth 2.0، يعتبر ربط الهوية المفتوح (OIDC) خيارًا طبيعيًا للعديد من المطورين. نظرًا لأن OIDC هو طبقة مصادقة مبنية على OAuth 2.0، قد تشعر بالألفة عندما تبدأ العمل مع OIDC. لنبدأ!
ما هو خادم OIDC، ولماذا يجب أن أدمج خادم OIDC؟
خادم OIDC، أو مزود الهوية، هو نظام مركزي يدير المصادقة والتفويض للمستخدمين. كما ناقشنا في لماذا تحتاج إلى نظام هوية مركزي للأعمال المتعددة التطبيقات، فإن النظام المركزي للهوية له فوائد عديدة.
لنقل أن مشروعك يبدأ بتطبيق ويب بسيط، ولديه مصادقة مدمجة:
بينما ينمو مشروعك، تحتاج إلى تقديم إصدار جوال:
سيكون تجربة سيئة للمستخدمين إذا احتاجوا إلى إنشاء حساب لكل تطبيق. نظرًا لأنك بدأت بتطبيق ويب، فإنك تتيح لتطبيق الجوال التواصل مع تطبيق الويب للمصادقة:
الآن، يتم تقديم خدمة API جديدة. نظرًا لأنها خدمة للمستخدمين المدفوعين، تحتاج إلى التأكد من أن المستخدم مصادق عليه ومفوض للوصول إلى الخدمة. لتحقيق ذلك، يمكنك تمرير الخدمة من خلال تطبيق الويب:
أو، استخدام تقنية الرموز للتحقق من المستخدم، والتحقق من صلاحية الرمز من خلال الحديث مع تطبيق الويب في الخدمة. وبالتالي يمكن لتطبيق الجوال استخدام الخدمة مباشرة:
الأمور تصبح معقدة. لذلك تقرر تقسيم منطق المصادقة والتفويض إلى خدمة منفصلة:
قد تكون عملية إعادة البناء مؤلمة. قد تلاحظ أن تعقيدها سيزداد بشكل كبير مع زيادة التطبيقات والخدمات في المشروع. والأسوأ من ذلك، قد تحتاج إلى الحفاظ على طرق متعددة للمصادقة مثل تسجيل الدخول بدون كلمة مرور، تسجيل الدخول الاجتماعي، SAML، إلخ.
لهذا السبب من الأفضل تقديم مزود هوية في البداية عندما يكون لديك خطة لتوسيع مشروعك.
أفضل الممارسات لتكامل خادم OIDC
العثور على مزود OIDC
هناك العديد من مزودي OIDC المتاحين في السوق. يمكنك اختيار واحد بناءً على متطلباتك وتفضيلاتك. طالما أن المزود متوافق مع OIDC، فإنه سيلعب نفس الدور في مشروعك.
ماذا تعني "الموضوع" و"العميل" و"الجمهور" في OIDC؟
لتبسيط المفهوم، يمكننا التفكير في أن الموضوع هو الكيان الذي يطلب الوصول إلى الجمهور عبر العميل.
لنرى بعض السيناريوهات النموذجية:
1. مستخدم ينقر على زر تسجيل الدخول في تطبيق ويب
في تطبيق ويب تقليدي وعرضٍ على جانب الخادم، يكون الواجهة الأمامية والخلفية مرتبطين. لنقل أن تطبيق الو يب يقدم كلا من الواجهة الأمامية والخلفية:
- الموضوع: المستخدم
- الجمهور: خادم OIDC
- العميل: تطبيق الويب
قد يبدو لك أن الجمهور هو خادم OIDC. في الواقع، هو المفتاح لتحقيق تجربة SSO (تسجيل الدخول الموحد) للمستخدم النهائي. دعنا نرى مخطط تسلسلي مبسط لتدفق رمز التفويض:
رمز
هو رمز لمرة واحدة يمكن تبادله لمجموعة من الرموز، مثل رمز الوصول، ورمز التعريف، ورمز التحديث. لا بأس إذا لم تفهم جميع هذه الرموز في هذه اللحظة. عندما نتحرك للأمام، ستحصل على فهم أفضل لها.
في الحالة أعلاه، لا يحتاج المستخدم إلى تسجيل الدخول مرة أخرى عندما ينتقل إلى تطبيق آخر لأن المستخدم (الموضوع) قد تم التحقق منه بالفعل بواسطة خادم OIDC (الجمهور).
2. مستخدم يستخدم تطبيق صفحة واحدة
في تطبيق صفحة واحدة (أو تطبيق جوال)، يكون الواجهة الأمامية والخلفية مفصولين. لنقل أن الخلفية هي خدمة API:
- الموضوع: المستخدم
- الجمهور: خدمة API
- العميل: تطبيق صفحة واحدة (SPA)
مخطط تسلسلي مبسط مع تدفق رمز التفويض:
نظرًا لأن خدمة API غير تفاعلية، يحتاج SPA لاستخدام رمز الوصول مع خدمة API كالجمهور (aud في الرمز).
لماذا لا يزال خادم OIDC جمهورًا؟
من الناحية التقنية، يمكنك إزالة خادم OIDC من قائمة الجمهور. نظرًا لأنك في معظم الحالات، ستحتاج إلى معلومات المستخدم من خادم OIDC (الأمر الذي يتطلب أن يكون خادم OIDC هو الجمهور)، من الأفضل دائمًا تضمين خادم OIDC في قائمة الجمهور عندما يتعلق الأمر بتفاعل المستخدم.
انتظر، أنت تقول أنه يمكننا أن يكون لدينا جمهور متعدد في طلب التفويض؟
بالضبط! تذكر أن OIDC مبني على OAuth 2.0، من الممكن الاستفادة من RFC 8707: مؤشرات الموارد لـ OAuth 2.0 في طلب التفويض لتحديد جمهور متعدد. يتطلب ذلك دعمًا من كل من المنحة وخادم OIDC. Logto يدعم هذه الميزة بشكل افتراضي.
3. اتصال من آلة إلى آلة
لنقل أن لديك خدمة A تحتاج إلى الاتصال بخدمة B:
- الموضوع: خدمة A
- الجمهور: خدمة B
- العميل: خدمة A
مخطط تسلسلي مبسط مع منحة بيانات اعتمادات العميل:
عندما تحتاج خدمة B للتواصل مع خدمة A، يتم تبادل الأدوار ببساطة.
ملخص
- الموضوع: يمكن أن يكون مستخدمًا أو خدمة أو أي كيان يحتاج إلى الوصول إلى الجمهور.
- العميل: يمكن أن يكون تطبيق ويب أو تطبيق جوال أ, أي كيان يبدأ الطلب أو يتصرف نيابة عن الموضوع.
- الجمهور: يمكن أن تكون خدمة أو API أو أي كيان يقدم الوصول إلى الموضوع.
ما هي رموز الوصول، ورموز التعريف، ورموز التحديث؟
هناك ثلاثة أنواع من الرموز التي قد تواجهها عند العمل مع OIDC:
- رمز الوصول: يُستخدم للوصول إلى الجمهور. يمكن أن يكون JWT (رمز ويب JSON) أو رمز مبهم (عادةً سلسلة عشوائية).
- رمز التعريف: رمز خاص بـ OIDC يحتوي على معلومات المستخدم. دائمًا ما يكون رمزا JWT. يمكن أن يفك الشفرة العميل للحصول على معلومات المستخدم.
- رمز التحديث: يُستخدم للحصول على مجموعة جديدة من الرموز عند انتهاء صلاحية رمز الوصول أو رمز التعريف.
للحصول على تفسير مفصل لهذه الرموز، يمكنك الرجوع إلى فهم رموز التحديث، ورموز الوصول، ورموز التعريف في بروتوكول OIDC.
في السيناريوهات أعلاه 1 و2، يُشير المصطلح طلب التفويض إلى طلب للحصول على مجموعة من الرموز عبر منحة محددة.
عندما تسير كل الأمور على ما يرام، سيتم إرجاع مجموعة من الرموز في الخطوة "تبادل الرموز باستخدام رمز
". تعتمد الرموز المتاحة في المجموعة على عدة عوامل، وخاصةً على معلمة النطاق
في طلب التفويض. للبساطة، سنفترض أن جميع الرموز يتم إرجاعها في المجموعة. بمجرد انتهاء صلاحية رمز الوصول، يمكن للعميل استخدام رمز التحديث للحصول على مجموعة جديدة من الرموز دون تفاعل المستخدم.
بالنسبة للسيناريو 3، الأمر أبسط لأن منحة بيانات اعتماد العميل تعيد فقط رمز الوصول.
كيفية التعامل مع عدة جمهور في OIDC؟
قد تلاحظ أن رمز الوصول الواحد فقط هو الذي يتم إرجاعه في المرة الواحدة. كيف يمكننا معالجة حالة حيث يحتاج العميل للوصول إلى عدة جمهور؟
هناك حلان شائعان:
تحديد resource
في طلب تبادل الرموز
عندما يقوم العميل بتبادل الرمز للحصول على الرموز، يمكنه تحديد معلمة resource
في الطلب. سيعيد خادم OIDC رمز وصول لنفس الجمهور إذا كان ذلك مناسبًا.
إليك مثال غير معياري:
ثم سيقوم خادم OIDC بإرجاع رمز وصول لجمهور API_SERVICE
، إذا كان ذلك مناسبًا.
استخدام رمز التحديث للحصول على رمز وصول جديد
مع RFC 8707، يمكن للعميل حتى تحديد جمهور متعدد باستخدام معلمة resource
عدة مرات. الآن، إذا كان رمز التحديث متاحاً للعميل، يمكن للعميل تحديد الجمهور في معلمة resource
عند تحديث الرمز.
إليك مثال غير معياري:
له نفس التأثير مثل الحل السابق. وفي الوقت نفسه، لا تزال الجماهير المعطاة الأخرى متاحة لطلبات الرمز المستقبلية.
منحة بيانات اعتماد العميل
يمكنك أيضا استخدام معلمة resource
في منحة بيانات اعتماد العميل لتحديد الجمهور. لا توجد مشكلة في الجمهور المتعدد في هذه المنحة لأنك يمكنك دائمًا طلب رمز وصول جديد لجمهور مختلف عن طريق إرسال طلب رمز آخر.
حماية خدمة API الخاصة بك
تحتوي "خدمة API" في السيناريو 2 و "خدمة B" في السيناريو 3 على شيء مشترك: يحتاجون إلى التحقق من صحة رمز الوصول لتحديد ما إذا كان الطلب مفوضًا. اعتمادًا على تنسيق رمز الوصول، قد يختلف عملية التحقق.
- الرمز المبهم: تحتاج خدمة API للاتصال بخادم OIDC للتحقق من صحة الرمز. عادةً ما يتم توفير نقطة فحص بواسطة خادم OIDC لهذا الغرض.
- JWT: يمكن لخدمة API التحقق من صحة الرمز محليًا عن طريق التحقق من التوقيع والمطالبات في الرمز. عادةً ما يوفر خادم OIDC مجموعة مفاتيح ويب JSON (JWKS) (
jwks_uri
) لتقوم خدمة API بالحصول على المفتاح العام للتحقق من التوقيع.
إذا كنت جديدًا في موضوع JWT، يمكنك الرجوع إلى ما هو رمز ويب JSON (JWT)؟. في الحقيقة، عادةً لا داعي للتحقق من التوقيع وتأكيد المطالبات يدويًا لأن هناك العديد من المكتبات التي يمكنها القيام بذلك من أجلك، مثل jose لـ Node.js ومتصفحات الويب.
تأكيد المطالبات
إضافة إلى التحقق من توقيع JWT، يجب على خدمة API دائمًا التحقق من المطالبات في الرمز:
iss
: مصدر الرمز. يجب أن يتطابق مع عنوان URL لمصدر خادم OIDC.aud
: جمهور الرمز. يجب أن يتطابق مع قيمة جمهور خدمة API (عادةً URI صالح).exp
: وقت انتهاء صلاحية الرمز. يجب على خدمة API رفض الرمز إذا انتهت صلاحيته.scope
: نطاقات الرمز (الأذونات). يجب على خدمة API التحقق مما إذا كان النطاق المطلوب موجودًا في الرمز.
المطالبات الأخرى، مثل sub
(الموضوع) وiat
(المصدر في) مهمان أيضًا في بعض الحالات. إذا كان لديك تدابير أمان إضافية، تحقق من المطالبات وفقًا لذلك.
التفويض
تبقى هناك سؤال لم يُجاب عليه: كيف نحدد ما إذا كان يمكن منح نطاق (أي إذن) لموضوع؟
السؤال الواحد يؤدي إلى عالم كامل من التفويض، وهو خارج نطاق هذه المقالة. باختصار، هناك بعض الأساليب الشائعة مثل RBAC (التحكم في الوصول المعتمد على الدور) وABAC (التحكم في الوصول المعتمد على السمة). إليك بعض الموارد لتبدأ:
ملاحظات ختامية
تقديم خادم OIDC في مشروعك هو خطوة كبيرة. يمكن أن يحسن بشكل كبير من الأمان وقابلية التوسع لمشروعك. في الوقت نفسه، قد يستغرق الأمر بعض الوقت لفهم المفاهيم والتفاعلات بين المكونات.
اختيار مزود OIDC جيد يلبي متطلباتك وتفضيلاتك يمكن أن يقلل بشكل ملحوظ من تعقيد عملية التكامل، حيث يقدم المزود عادةً الحزمة الكاملة، بما في ذلك خادم OIDC، وآليات التفويض، وحزم التطوير SDK، والميزات المؤسسة التي قد تحتاجها في المستقبل.
آمل أن يساعدك هذا الدليل في فهم الأساسيات لتكامل خادم OIDC. إذا كنت تبحث عن واحد لتبدأ به، أنصحك بأنانية بـ Logto، بنية هويتنا للبنائين.