
1. با استفاده از Authorization Code Flow
سامانه SSO (Single Sign-On) یکی از رایجترین و امنترین روشهای احراز هویت در سازمانها است. در این راهنما، مراحل پیادهسازی یکپارچهسازی سامانهها با Authorization Code Flow بر پایه استاندارد OpenID Connect و پروتکل OAuth 2.0 را شرح میدهیم.
📌 مرحله اول: تنظیمات اولیه در سامانه SSO
برای شروع یکپارچهسازی، ابتدا باید تنظیمات زیر را در پنل مدیریتی سامانه SSO برای کلاینت (Client) مورد نظر انجام دهید:
-
فعالسازی Authorization Code Flow
-
ثبت دقیق redirect URI سامانه در بخش آدرسهای بازگشت معتبر
-
غیرفعال کردن گزینهی PKCE (Proof Key for Code Exchange) برای سادهسازی فرآیند
🔄 مرحله دوم: هدایت کاربر به SSO برای دریافت Authorization Code
سامانهی شما کاربر را به آدرس Authorization Endpoint هدایت میکند. آدرس نمونه:
پارامترهای ضروری:
-
client_id
: شناسه کلاینت در سامانه SSO -
redirect_uri
: آدرس بازگشت پس از احراز هویت -
response_type
: باید مقدارcode
باشد -
scope
: شاملopenid
برای فعالسازی OIDC -
state
: رشتهای امن برای جلوگیری از حملات CSRF
نمونه کامل لینک:
پس از احراز هویت موفق، کاربر به شکل زیر بازگردانده میشود:
🔐 مرحله سوم: دریافت Access Token از SSO
کلاینت باید با ارسال یک درخواست POST به Token Endpoint، توکن دریافت کند:
مقادیر مورد نیاز در body:
-
client_id
-
client_secret
-
grant_type=authorization_code
-
code
: کدی که در مرحله قبل دریافت شد -
redirect_uri
: باید با مقدار قبلی یکسان باشد
در پاسخ، Access Token و معمولاً ID Token برای استفاده در برنامه دریافت میشود.
✅ مزایای استفاده از Authorization Code Flow در سامانه SSO
-
🔒 امنیت بالا: چون توکن در سمت سرور تبادل میشود، نه مرورگر
-
🌐 سازگاری با معماریهای SPA و Backend
-
🔁 قابلیت گسترش برای MFA و Refresh Token
🧩 نکات نهایی برای پیادهسازی موفق سامانه SSO
-
استفاده از HTTPS در تمام مسیرها الزامی است
-
حتماً از مقدار
state
برای محافظت در برابر حملات استفاده کنید -
بهروز نگه داشتن
client_secret
و محدودسازی آن در سرور بسیار مهم است -
ترکیب با MFA امنیت را دوچندان میکند
2. از طریق Authorization Code Flow with PKCE
📌 مقدمه
Authorization Code Flow with PKCE یک نسخه ایمنشده از Authorization Code Flow است که برای برنامههای Public (مثل اپلیکیشنهای موبایل یا SPA) طراحی شده است. این روش بدون نیاز به تبادل client_secret، امنیت ارتباط میان کلاینت و سامانه SSO را افزایش میدهد و با استاندارد RFC 7636 سازگار است.
🛠️ پیشنیازهای تنظیم در سامانه SSO
قبل از شروع پیادهسازی، مطمئن شوید تنظیمات زیر در پنل مدیریت سامانه (Client) در SSOPlus انجام شده باشد:
-
فعالسازی Authorization Code Flow
-
ثبت دقیق redirect URI در بخش آدرسهای بازگشت معتبر
-
تنظیم مقدار Code Challenge Method بر روی
S256
در بخش تنظیمات OpenID Connect
⚠️ توجه: استفاده از حالت
plain
توصیه نمیشود زیرا امنیت رمزنگاری را تضعیف میکند.
🧩 گام اول: تولید Code Verifier و Code Challenge
سامانه کلاینت ابتدا باید یک جفت کلید شامل Code Verifier و Code Challenge تولید کند:
-
Code Verifier: رشتهای تصادفی با طول بین 43 تا 128 کاراکتر، شامل حروف، اعداد و کاراکترهای مجاز مانند
-
,.
,_
,~
مطابق با RFC 7636. -
Code Challenge:
-
اگر متد
plain
: مقدار آن برابر باcode_verifier
خواهد بود. -
اگر متد
S256
: طبق فرمول زیر محاسبه میشود:
-
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
🧭 گام دوم: ارسال درخواست به Authorization Endpoint
کلاینت کاربر را به آدرس Authorization Endpoint در سامانه SSO هدایت میکند تا احراز هویت و دریافت Authorization Code انجام شود.
🔸 پارامترهای ارسالی:
-
client_id
-
redirect_uri
-
response_type=code
-
scope=openid profile ...
-
state
-
code_challenge
-
code_challenge_method=S256
📎 نمونه URL:
https://www.sso.com/auth/realms/sso/protocol/openid-connect/auth?response_type=code&client_id=test&scope=openid%20profile%20email&state=132&redirect_uri=http://localhost:4200&code_challenge=Ns6zRgtJjVSLbqe332fQSZP6gtUh_pH3YZ55XvATBEM&code_challenge_method=S256
📎 نمونه پاسخ از سامانه SSO:
http://localhost:4200/?state=132&code=5504dcd0-7dc1-49d0-95a3-19614c60723f...
🔄 گام سوم: دریافت Access Token از Token Endpoint
پس از دریافت Authorization Code، کلاینت با ارسال یک درخواست POST به Token Endpoint در سامانه SSO، توکن را دریافت میکند.
🔸 پارامترهای POST در Body:
-
client_id
-
client_secret
(فقط برای کلاینتهای confidential) -
grant_type=authorization_code
-
code
-
code_verifier
-
redirect_uri
📎 آدرس Token Endpoint:
https://www.sso.com/auth/realms/sso/protocol/openid-connect/token
📎 نمونه پاسخ:
{
"access_token": "eyJhbGciOi...",
"id_token": "eyJhbGciOi...",
"expires_in": 3600,
...
}
✅ مزایای استفاده از Authorization Code Flow with PKCE در سامانه SSO
-
امنیت بالا بدون نیاز به client_secret
-
مناسب برای اپلیکیشنهای موبایل و SPA
-
پیشگیری از حملات CSRF و code injection
-
سازگار با تمام کلاینتهای public و confidential
🔍 Fragment چیست؟
Fragment بخش انتهایی یک URL است که با #
شروع میشود و توسط مرورگر تجزیه نمیشود و به سرور ارسال نمیشود.
مثال:
http://example.com/callback#access_token=abc123&id_token=xyz
در این مثال، #access_token=abc123
یک fragment است.
🧩 Fragment در Flowهای احراز هویت چه کاربردی دارد؟
در Implicit Flow (که امروزه منسوخ شده)، توکنها معمولاً بهصورت fragment در URL بازگشت ارسال میشدند.
اما در Authorization Code Flow (که SSOPlus از آن استفاده میکند)، توکنها در body درخواست POST (مرحله دوم) دریافت میشوند، نه در URL، بنابراین:
✅ در Authorization Code Flow واقعی، نباید توکنها در fragment یا query string بازگردند.
❗ پس چرا گاهی Fragment دیده میشود؟
در بعضی پیادهسازیها، توسعهدهندهها از fragment برای نگهداری context در سمت کلاینت استفاده میکنند، مثلاً:
-
نگهداری مسیر قبلی کاربر برای redirect بعدی
-
حفظ وضعیت رابط کاربری (tab فعال، scroll position و …)
-
استفاده توسط فریمورکهای front-end (مثل Angular routing)
مثال:
https://client-app.com/callback?code=abc123&state=xyz#section=dashboard
در این حالت، بخش #section=dashboard
فقط برای کلاینت مهم است و هیچ تاثیری در پروتکل احراز هویت ندارد.
⚠ نکته مهم امنیتی:
از قرار دادن داده حساس (مثل access_token) در fragment یا query string خودداری کن، چون:
-
در لاگ مرورگر یا تاریخچه مرورگر باقی میماند
-
توسط ابزارهای third-party قابل رهگیری است
-
قابل ذخیرهسازی در cache URL است
✅ نتیجه نهایی:
-
Fragment بخشی از استاندارد OAuth برای Authorization Code Flow نیست
-
اگر در URL برگشتی دیده شود، فقط برای استفاده داخلی کلاینت است (مثلاً frontend SPA)
-
برای احراز هویت، فقط به query params (
code
,state
) و سپس درخواست POST برای توکن نیاز دارید.
🔐 تفاوت کلاینتهای Confidential و Public در سامانه SSO
ویژگی | کلاینت Public | کلاینت Confidential |
---|---|---|
امنیت سمت کلاینت | پایین (قابل معاینه توسط کاربر) | بالا (در سمت سرور اجرا میشود) |
نیاز به client_secret |
❌ ندارد | ✅ الزامی است |
کاربرد | اپ موبایل، SPA | برنامههای سروری، Backend |
پشتیبانی از PKCE | ✅ ضروری | 🔄 اختیاری (اما توصیه شده برای امنیت بیشتر) |
⚙️ تفاوت در پیادهسازی Authorization Code Flow
1. ارسال درخواست به Authorization Endpoint
در هر دو حالت تقریباً مشابه است و شامل موارد زیر است:
-
client_id
-
redirect_uri
-
response_type=code
-
scope
-
state
-
code_challenge
(در صورت استفاده از PKCE) -
code_challenge_method
(معمولاً S256)
2. دریافت Access Token از Token Endpoint
🔸 کلاینت Public:
-
استفاده از
code_verifier
برای احراز هویت -
نیازی به
client_secret
ندارد
🔸 کلاینت Confidential:
-
باید هم
client_secret
و همcode_verifier
را ارسال کند (اگر از PKCE استفاده شده) -
اگر از PKCE استفاده نشده، فقط
client_id
وclient_secret
کافی است
📝 مثال درخواست توکن (Confidential + PKCE):
POST /token
Content-Type: application/x-www-form-urlencoded
client_id=backend-app
&client_secret=abc123
&code=xyz
&code_verifier=base64random
&grant_type=authorization_code
&redirect_uri=https://backend.com/callback
🛡️ آیا برای کلاینتهای Confidential استفاده از PKCE ضروری است؟
-
از لحاظ فنی: اجباری نیست
-
از لحاظ امنیتی: شدیداً توصیه میشود برای جلوگیری از سرقت Authorization Code (مثلاً حملهی code interception)
✅ نتیجهگیری
سؤال | پاسخ |
---|---|
آیا پیادهسازی برای Confidential فرق دارد؟ | بله، تفاوت اصلی در نیاز به client_secret و امنیت بالاتر سمت سرور است. |
آیا باید از PKCE استفاده کنیم؟ | بله، برای امنیت بیشتر حتی در Confidential هم توصیه میشود. |
آیا کلاینتهای Public و Confidential از یک Flow استفاده میکنند؟ | بله، هر دو از Authorization Code Flow استفاده میکنند، ولی در مرحله دریافت توکن، احراز هویت متفاوتی دارند. |