OpenID Connect: ترخيص التطبيقات الداخلية من عام إلى قياسي

قبل بضعة أشهر ، كنت أقوم بتطبيق خادم OpenID Connect للتحكم في الوصول إلى مئات تطبيقاتنا الداخلية. من تطوراتنا الخاصة ، وعلى نطاق أصغر ، انتقلنا إلى المعيار المقبول بشكل عام. يعمل الوصول من خلال خدمة مركزية على تبسيط العمليات الرتيبة بشكل كبير ، ويقلل من تكلفة تنفيذ التراخيص ، ويسمح لك بالعثور على العديد من الحلول الجاهزة وليس كسر عقلك عند تطوير حلول جديدة. في هذه المقالة سأتحدث عن هذا التحول وعن المطبات التي تمكنا من ملؤها.

مقدمة

ذات مرة ... كيف بدأ كل شيء


قبل بضع سنوات ، عندما كان هناك الكثير من التطبيقات الداخلية للتحكم اليدوي ، كتبنا تطبيقًا للتحكم في الوصول داخل الشركة. كان تطبيق Rails بسيطًا مرتبطًا بقاعدة بيانات تحتوي على معلومات حول الموظفين ، حيث تم تكوين الوصول إلى وظائف مختلفة. ثم رفعنا أول SSO ، والذي كان قائمًا على التحقق من الرموز المميزة من العميل وخادم التفويض ، وتم إرسال الرمز المميز في شكل مشفر مع العديد من المعلمات وفحصه على خادم التفويض. لم يكن هذا هو الخيار الأكثر ملاءمة ، حيث كان من الضروري في كل تطبيق داخلي وصف طبقة كبيرة من المنطق ، وتمت مزامنة قاعدة الموظفين تمامًا مع خادم التفويض.

بعد مرور بعض الوقت ، قررنا تبسيط مهمة التفويض المركزي. تم نقل SSO إلى الموازن. باستخدام OpenResty على Lua ، أضافوا نموذجًا للتحقق من الرموز المميزة ، ومعرفة التطبيق الذي كان الطلب موجودًا فيه ، ويمكنهم التحقق مما إذا كان هناك وصول إليه. يبسط هذا النهج إلى حد كبير مهمة التحكم في الوصول إلى التطبيقات الداخلية - في رمز كل تطبيق ، لم يعد من الضروري وصف المنطق الإضافي. ونتيجة لذلك ، أغلقنا حركة المرور خارجيًا ، ولم يكن التطبيق نفسه يعرف أي شيء عن التفويض.

ومع ذلك ، ظلت إحدى المشاكل دون حل. ماذا عن التطبيقات التي تحتاج إلى معلومات حول الموظفين؟ يمكنك كتابة واجهة برمجة تطبيقات لخدمة المصادقة ، ولكن بعد ذلك سيتعين عليك إضافة منطق إضافي لكل تطبيق. بالإضافة إلى ذلك ، أردنا التخلص من الاعتماد على أحد تطبيقاتنا المكتوبة ذاتيًا ، والموجهة نحو الترجمة إلى OpenSource ، على خادم التفويض الداخلي الخاص بنا. سنتحدث عنه في وقت آخر. كان الحل لكلتا المشكلتين OAuth.

إلى المعايير المقبولة بشكل عام


OAuth هو معيار تفويض مقبول ومفهوم بشكل عام ، ولكن نظرًا لأن وظائفه ليست كافية ، فقد بدأ على الفور النظر في OpenID Connect (OIDC). OIDC نفسه هو التنفيذ الثالث لمعيار المصادقة المفتوحة الذي امتد إلى الوظيفة الإضافية عبر بروتوكول OAuth 2.0 (بروتوكول المصادقة المفتوح). يغلق هذا الحل مشكلة نقص البيانات حول المستخدم النهائي ، ويتيح أيضًا تغيير موفر التفويض.

ومع ذلك ، لم نختار موفرًا معينًا وقررنا إضافة التكامل مع OIDC لخادم التفويض الحالي. لصالح هذا الحل ، OIDC مرنة للغاية من حيث تفويض المستخدم النهائي. وبالتالي ، كان من الممكن تنفيذ دعم OIDC على خادم التفويض الحالي.

صورة

طريقتنا لتنفيذ خادم OIDC الخاص بنا


1) أحضروا البيانات إلى النموذج المطلوب


لدمج OIDC ، تحتاج إلى إحضار بيانات المستخدم الحالية بطريقة مفهومة للمعيار. في OIDC ، يسمى هذا المطالبات. العلامات التجارية هي بشكل أساسي الحقول النهائية في قاعدة بيانات المستخدم (الاسم ، البريد الإلكتروني ، الهاتف ، إلخ). هناك قائمة قياسية بالعلامات التجارية ، وكل ما لم يتم تضمينه في هذه القائمة يعتبر مخصصًا. لذلك ، النقطة الأولى التي تحتاج إلى الانتباه إليها إذا كنت ترغب في اختيار مزود OIDC الحالي هي القدرة على تخصيص العلامات التجارية الجديدة بشكل ملائم.

يتم دمج مجموعة العلامات التجارية في المجموعة الفرعية التالية - النطاق. أثناء الترخيص ، لا يُطلب الوصول إلى علامات تجارية محددة ، ولكن إلى النطاقات ، حتى إذا لم تكن هناك حاجة إلى بعض السمات المميزة من النطاق.

2) نفذ المنح اللازمة


الجزء التالي من تكامل OIDC هو اختيار وتنفيذ أنواع التفويض ، ما يسمى المنح. يعتمد السيناريو الإضافي لتفاعل التطبيق المحدد مع خادم التفويض على المنحة المحددة. يتم عرض مخطط تقريبي لاختيار المنحة الصحيحة في الشكل أدناه.

صورة

بالنسبة للتطبيق الأول ، استخدمنا المنحة الأكثر شيوعًا - رمز التفويض. اختلافه عن الآخرين هو أنه يتكون من ثلاث خطوات ، أي يمر التحقق الإضافي. أولاً ، يقدم المستخدم طلبًا للحصول على إذن التفويض ، ويتلقى رمز التفويض - رمز التفويض ، ثم باستخدام هذا الرمز المميز ، كما لو كان مع تذكرة سفر ، يطلب رمز وصول. تعتمد جميع التفاعلات الرئيسية لسيناريو التفويض هذا على عمليات إعادة التوجيه بين التطبيق وخادم التفويض. اقرأ المزيد عن هذه المنحة هنا .

يلتزم OAuth بمفهوم أن الرموز المميزة للدخول التي يتم تلقيها بعد التفويض يجب أن تكون مؤقتة وتفضل تغييرها كل 10 دقائق في المتوسط. إن منح كود التفويض هو فحص من ثلاث خطوات من خلال عمليات إعادة التوجيه ؛ كل 10 دقائق ، فإن تحول هذه الخطوة ، بصراحة ، ليس تجربة ممتعة للعيون. لحل هذه المشكلة ، هناك منحة أخرى - Refresh Token ، والتي قمنا بنشرها أيضًا. كل شيء أبسط هنا. أثناء الاختبار ، من منحة أخرى ، بالإضافة إلى رمز الوصول الرئيسي ، يتم إصدار واحد آخر - رمز التحديث ، والذي يمكن استخدامه مرة واحدة فقط ، وعمره ، كقاعدة ، أطول بشكل ملحوظ. مع رمز التحديث هذا ، عندما ينتهي TTL (وقت البقاء) لرمز الوصول الرئيسي ، سيأتي طلب رمز وصول جديد إلى نقطة نهاية منحة أخرى. تتم إعادة تعيين رمز تحديث المستخدم على الفور.مثل هذا الفحص يتكون من خطوتين ويمكن إجراؤه في الخلفية ، بشكل غير مرئي للمستخدم.

3) تنسيقات إخراج بيانات المستخدم المخصصة


بعد تنفيذ المنح المختارة ، يعمل الترخيص ، تجدر الإشارة إلى استلام البيانات حول المستخدم النهائي. لدى OIDC نقطة نهاية منفصلة لذلك ، حيث يمكنك طلب بيانات المستخدم مع رمز الوصول الحالي الخاص بك وعند الاقتضاء. وإذا لم تتغير بيانات المستخدم في كثير من الأحيان ، وتحتاج إلى متابعة البيانات الحالية عدة مرات ، يمكنك الوصول إلى قرار مثل رموز JWT. هذه الرموز المميزة مدعومة أيضًا بالمعيار. يتكون رمز JWT نفسه من ثلاثة أجزاء: الرأس (معلومات حول الرمز المميز) ، والحمولة (أي بيانات ضرورية) والتوقيع (التوقيع ، الرمز المميز موقّع من الخادم ويمكنك التحقق من مصدر توقيعه في المستقبل).

في تطبيق OIDC ، يُسمى الرمز المميز JWT id_token. يمكن طلبها مع رمز وصول منتظم ، وكل ما تبقى هو التحقق من التوقيع. يحتوي خادم المصادقة على نقطة نهاية منفصلة لهذا مع مجموعة من المفاتيح العامة بتنسيق JWK . وبالحديث عن هذا ، تجدر الإشارة إلى أن هناك نقطة نهاية أخرى ، استنادًا إلى معيار RFC5785 ، تعكس التكوين الحالي لخادم OIDC. يحتوي على جميع عناوين نقاط النهاية (بما في ذلك عنوان سلسلة المفاتيح العامة المستخدمة للتوقيع) والعلامات التجارية والمجالات المدعومة وخوارزميات التشفير المستخدمة والمنح المدعومة وما إلى ذلك.

على سبيل المثال على Google:
{
 "issuer": "https://accounts.google.com",
 "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
 "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
 "token_endpoint": "https://oauth2.googleapis.com/token",
 "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
 "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
 "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
 "response_types_supported": [
  "code",
  "token",
  "id_token",
  "code token",
  "code id_token",
  "token id_token",
  "code token id_token",
  "none"
 ],
 "subject_types_supported": [
  "public"
 ],
 "id_token_signing_alg_values_supported": [
  "RS256"
 ],
 "scopes_supported": [
  "openid",
  "email",
  "profile"
 ],
 "token_endpoint_auth_methods_supported": [
  "client_secret_post",
  "client_secret_basic"
 ],
 "claims_supported": [
  "aud",
  "email",
  "email_verified",
  "exp",
  "family_name",
  "given_name",
  "iat",
  "iss",
  "locale",
  "name",
  "picture",
  "sub"
 ],
 "code_challenge_methods_supported": [
  "plain",
  "S256"
 ],
 "grant_types_supported": [
  "authorization_code",
  "refresh_token",
  "urn:ietf:params:oauth:grant-type:device_code",
  "urn:ietf:params:oauth:grant-type:jwt-bearer"
 ]
}


وبالتالي ، باستخدام id_token ، يمكنك نقل جميع العلامات المميزة الضرورية إلى حمولة الرمز المميز وعدم الاتصال بخادم التفويض في كل مرة لطلب بيانات حول المستخدم. عيب هذا النهج هو أن تغيير بيانات المستخدم من الخادم لا يأتي على الفور ، ولكن مع رمز وصول جديد.

نتائج التنفيذ


لذا ، بعد تنفيذ خادم OIDC الخاص بنا وإعداد اتصالات إليه من جانب التطبيق ، قمنا بحل مشكلة نقل معلومات المستخدم.
نظرًا لأن OIDC هو معيار مفتوح ، لدينا الفرصة لاختيار مزود خدمة أو تنفيذ خادم موجود. لقد جربنا Keycloak ، والذي تبين أنه ملائم للغاية للتهيئة ، بعد إعداد وتهيئة تكوينات الاتصال على جانب التطبيق ، فهو جاهز للعمل. على جانب التطبيق ، يبقى فقط لتغيير تكوين الاتصال.

الحديث عن الحلول الموجودة


كجزء من مؤسستنا ، كأول خادم OIDC ، قمنا بتجميع التنفيذ لدينا ، والذي تم استكماله حسب الحاجة. بعد مراجعة مفصلة للحلول الجاهزة الأخرى ، يمكننا القول أن هذه نقطة خلافية. عملت المخاوف من جانب مقدمي الخدمات حول نقص الوظائف اللازمة كحل لتنفيذ خادمهم ، بالإضافة إلى وجود نظام قديم كان فيه العديد من التفويضات المخصصة لبعض الخدمات وتم تخزين الكثير من البيانات حول الموظفين. ومع ذلك ، في عمليات التنفيذ الجاهزة ، هناك راحة للتكامل. على سبيل المثال ، Keycloak لديها نظام إدارة المستخدم الخاص بها ويتم تخزين البيانات مباشرة فيه ، ولن يكون من الصعب تجاوز مستخدميها هناك. لهذا ، يحتوي Keycloak على واجهة برمجة تطبيقات تسمح لك بتنفيذ جميع الخطوات اللازمة للنقل بشكل كامل.

مثال آخر على شهادة مصدقة ومثيرة للاهتمام ، في رأيي ، التنفيذ هو Ory Hydra. من المثير للاهتمام أنه يتكون من مكونات مختلفة. للتكامل ، ستحتاج إلى ربط خدمة إدارة المستخدم الخاصة بك بخدمة الترخيص الخاصة بهم والتوسيع حسب الضرورة.

Keycloak و Ory Hydra ليسا الحل الوحيد الجاهز. من الأفضل اختيار تنفيذ OpenID Foundation المعتمد. عادةً ما تحتوي هذه الحلول على شارة شهادة OpenID.

شهادة Openid


أيضًا ، لا تنس مقدمي الخدمات المدفوعين الحاليين إذا كنت لا ترغب في الاحتفاظ بخادم OIDC. هناك العديد من الخيارات الجيدة حتى الآن.

ماذا بعد


في المستقبل القريب ، سنغلق حركة المرور على الخدمات الداخلية بطريقة أخرى. نخطط لنقل SSO الحالي على الموازن باستخدام OpenResty إلى وكيل يعتمد على OAuth. هناك أيضًا العديد من الحلول الجاهزة هنا ، على سبيل المثال:
github.com/bitly/oauth2_proxy
github.com/ory/oathkeeper
github.com/keycloak/keycloak-gatekeeper

مواد إضافية


jwt.io - خدمة جيدة للتحقق من
openid.net/developers/certified JWT tokens - قائمة بتطبيقات OIDC المعتمدة

All Articles