
في الآونة الأخيرة ، كنت بحاجة إلى تنفيذ دعم لمصادقة المستخدم المجهول استنادًا إلى OpenId Connect و OAuth 2.0 على النظام الأساسي لـ ASP.NET Core. لن يتم شرح مواصفات هذه البروتوكولات هنا ، فهناك مقالات كاملة عن الهبر. دعنا نصل الى هذه النقطة.
لماذا نحتاج إلى رمز مجهول؟ لتخويل مستخدم مجهول على مورد واجهة برمجة التطبيقات ، وخاصة في بنية الخدمات المصغرة ، بالإضافة إلى ذلك ، يمكنه تغيير حالة تطبيقنا ، على سبيل المثال ، أحب Vasya قميصًا مع القطط ، ويضيفه إلى سلة المتجر عبر الإنترنت ، وربما يقدّم طلبًا كضيف. لفهم أنه كان فاسيلي ، يحتوي الرمز المجهول على معرف المستخدم المجهول ومعرف الجلسة. عند تسجيل الدخول إلى Vasily ، سيتم تضمين هذه المعلمات في الرمز المميز المصادق عليه.
بالإضافة إلى ذلك ، قد يحتوي رمز الوصول المجهول على أي عبارات (أو مطالبات) إضافية.
الأدوات
تطبيق
يحتوي IdentityServer4 على العديد من الأمثلة على GitHub.
إضافة دعم للرموز المجهولة بسيط للغاية:
سيناريو التفاعل
فكّر في الحصول على رمز مجهول للتدفق الضمني وتدفق كود التفويض .
طلب إذن نقطة
لمتابعة المواصفات ، يكون طلب الحصول على نقطة تفويض للتضمن الضمني كما يلي.
GET /connect/authorize? client_id=client1& scope=openid email api1& response_type=id_token token& redirect_uri=https://myapp/callback& state=abc& nonce=xyz& acr_values=0& response_mode=json
بالنسبة لتدفق كود التفويض ، طلب مماثل مع response_type = الكود (PKCE اختياري).
الاختلافات بين طلب عادي ومجهول في معلمتين:
- تشير المعلمة acr_values = 0 إلى تسجيل دخول مجهول. إذا كنت مهتمًا ، يمكنك قراءة مواصفات OpenId Connect .
- يستخدم response_mode = json المعلمة للاستجابة في شكل Json دون عمليات إعادة توجيه غير ضرورية.
تلقي الرمز المميز
اعتمادًا على حالة المصادقة ، يتم إرجاع رمز مميز مجهول أو مصادق.
التدفق الضمني
في هذه الحالة ، تستجيب نقطة التفويض في شكل Json ، بما في ذلك رمز الوصول.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1", "state": "abc", "session_state": <optional> }
تدفق إذن التفويض
مع هذا النهج ، تستجيب نقطة التفويض في شكل Json ، بما في ذلك رمز التفويض.
{ "code": <authorization_code>, "scope": "openid email api1", "state": "abc", "session_state": <optional> }
بعد ذلك ، تحتاج إلى تبادل رمز الرمز المميز باستخدام الطريقة القياسية.
نحن نشكل طلبًا لنقطة نهاية الرمز.
POST /connect/token client_id=client2& client_secret=secret& grant_type=authorization_code& code=`& redirect_uri=https://myapp/callback
نتيجة لذلك ، تستجيب نقطة نهاية الرمز المميز في شكل Json ، بما في ذلك رمز الوصول المميز.
{ "id_token": <id_token>, "access_token": <access_token>, "token_type": "Bearer", "expires_in": "2592000", "scope": "openid email api1" }
مقارنة الرموز مجهولة المصدر والموثقة
إذا كان خادم التخويل لا يحتوي على بيانات المصادقة ، فسنحصل على رمز مجهول.
{ "nbf": 1566849147, "exp": 1569441147, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "abda9006-5991-4c90-a88c-c96764027347", "auth_time": 1566849147, "idp": "local", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "anon" ] }
يمكنك تحديد أن المستخدم مجهول باستخدام طريقة المصادقة (amr).
سيتم إدراج معرف الجلسة (العامة) (ssid) ومعرف الموضوع (الفرعي) في الرمز المميز المصدق ، عند تسجيل دخول المستخدم التالي.
في حالة تسجيل دخول المستخدم ، نحصل على رمز موثوق به.
{ "nbf": 1566850295, "exp": 1566853895, "iss": "https://server", "aud": [ "https://server/resources", "api" ], "client_id": "client1", "sub": "bob", "auth_time": 1566850295, "idp": "local", "aid": "abda9006-5991-4c90-a88c-c96764027347", "ssid": "9e6453dbaf5ffdb03f08812f759d3cdf", "scope": [ "openid", "email", "api1" ], "amr": [ "pwd" ] }
كما ترون ، معرف المستخدم المجهول (المساعدة) يطابق الرمز الفرعي للرمز المجهول ، تمامًا مثل ssid. إذا لم يبدأ العميل تسجيل الدخول المجهول ، فسيحتوي الرمز المميز المصدق على ssid فقط.
وبالتالي ، يمكننا تفويض مستخدم مجهول وتحديد تصرفاته بعد دخول النظام.
استنتاج
في هذه المقالة ، درسنا سيناريو للحصول على رمز مميز مجهول / مصادق باستخدام IdentityServer4 مع ملحق AnonymousIdentity .
إذا كانت لديك أسئلة ، سأكون سعيدًا بالإجابة عليها في التعليقات.