مكتبة IdentityModel لـ OAuth 2.0 و OpenID Connect في C# (.NET)
\n\nعند تطوير تطبيقات الويب الحديثة، أو العملاء المحمولين، أو واجهات برمجة التطبيقات (API) من جانب الخادم على منصة .NET، تنشأ دائمًا تقريبًا الحاجة إلى التكامل مع موفري المصادقة الخارجيين (Google، GitHub، Microsoft، وغيرها) أو خادم الترخيص الخاص بك. IdentityModel هي مكتبة خفيفة الوزن ولكنها قوية لـ C#، توفر عميل OAuth مناسبًا للعمل مع بروتوكولات OAuth 2.0 و OpenID Connect. وهي تعتبر المعيار الفعلي في نظام .NET البيئي لتنفيذ تدفقات الترخيص.
\n\nفي هذه المقالة، سنشرح بالتفصيل كيفية استخدام IdentityModel لإنشاء عميل OAuth، والحصول على رموز الوصول وتحديثها. ستكون أمثلة الكود بلغة C# (.NET 6+).
\n\nالتثبيت والتوصيل
\n\nللبدء، قم بتثبيت الحزمة عبر NuGet Package Manager:
\n\ndotnet add package IdentityModel\n\nأو عبر وحدة تحكم مدير الحزم:
\n\nInstall-Package IdentityModel\n\nبعد التثبيت، ستحصل على إمكانية الوصول إلى امتدادات HttpClient، و DiscoveryClient، و TokenClient، وأدوات مساعدة أخرى.
السيناريو الأساسي: الحصول على رمز مميز عبر Client Credentials
\n\nيُستخدم هذا التدفق للمصادقة بين الخادم والخادم، عندما يطلب العميل (تطبيقك) رمزًا مميزًا نيابة عن نفسه، وليس عن المستخدم.
\n\nمثال على إعداد عميل OAuth:
\n\nusing IdentityModel.Client;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\npublic async Task<string> GetAccessTokenAsync()\n{\n var client = new HttpClient();\n\n // 1. الحصول على مستند الاكتشاف من خادم الترخيص\n var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");\n if (disco.IsError)\n {\n throw new Exception($"خطأ في الحصول على الاكتشاف: {disco.Error}");\n }\n\n // 2. طلب الرمز المميز باستخدام client_id و client_secret\n var tokenResponse = await client.RequestClientCredentialsTokenAsync(\n new ClientCredentialsTokenRequest\n {\n Address = disco.TokenEndpoint,\n ClientId = "your-client-id",\n ClientSecret = "your-client-secret",\n Scope = "api1 api2" // الأذونات المطلوبة\n });\n\n if (tokenResponse.IsError)\n {\n throw new Exception($"خطأ في الحصول على الرمز المميز: {tokenResponse.Error}");\n }\n\n return tokenResponse.AccessToken;\n}\n\nفي هذا المثال، نستخدم طرق الامتداد من مساحة الأسماء IdentityModel.Client. تقوم المكتبة تلقائيًا بمعالجة تسلسل JSON والرؤوس وتحليل الردود.
تدفق رمز الترخيص (بمشاركة المستخدم)
\n\nللتطبيقات ذات واجهة المستخدم (ASP.NET Core MVC، Blazor، سطح المكتب)، يُستخدم رمز الترخيص في الغالب. تتكامل IdentityModel مع Microsoft.AspNetCore.Authentication.OpenIdConnect، ولكنها توفر أيضًا أدوات منخفضة المستوى للتنفيذ اليدوي.
مثال على الحصول على رمز مميز بعد إعادة التوجيه باستخدام الكود:
\n\npublic async Task<TokenResponse> ExchangeCodeForTokenAsync(string authorizationCode, string redirectUri)\n{\n var client = new HttpClient();\n var disco = await client.GetDiscoveryDocumentAsync("https://your-auth-server.com");\n\n var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(\n new AuthorizationCodeTokenRequest\n {\n Address = disco.TokenEndpoint,\n ClientId = "your-client-id",\n ClientSecret = "your-client-secret",\n Code = authorizationCode,\n RedirectUri = redirectUri\n });\n\n return tokenResponse;\n}\n\nتحديث الرمز المميز (Refresh Token)
\n\nعادةً ما تكون صلاحية رموز الوصول (Access tokens) قصيرة (على سبيل المثال، ساعة واحدة).