راهنمای پیاده‌سازی سامانه SSO با سامانه SSO پلاس

راهنمای پیاده‌سازی SSO پلاس در سازمان‌ها

فهرست مطالب

راهنمای پیاده‌سازی سامانه SSO با سامانه SSO پلاس

1. با استفاده از Authorization Code Flow

سامانه SSO (Single Sign-On) یکی از رایج‌ترین و امن‌ترین روش‌های احراز هویت در سازمان‌ها است. در این راهنما، مراحل پیاده‌سازی یکپارچه‌سازی سامانه‌ها با Authorization Code Flow بر پایه استاندارد OpenID Connect و پروتکل OAuth 2.0 را شرح می‌دهیم.


📌 مرحله اول: تنظیمات اولیه در سامانه SSO

برای شروع یکپارچه‌سازی، ابتدا باید تنظیمات زیر را در پنل مدیریتی سامانه SSO برای کلاینت (Client) مورد نظر انجام دهید:

  1. فعال‌سازی Authorization Code Flow

  2. ثبت دقیق redirect URI سامانه در بخش آدرس‌های بازگشت معتبر

  3. غیرفعال کردن گزینه‌ی PKCE (Proof Key for Code Exchange) برای ساده‌سازی فرآیند


🔄 مرحله دوم: هدایت کاربر به SSO برای دریافت Authorization Code

سامانه‌ی شما کاربر را به آدرس Authorization Endpoint هدایت می‌کند. آدرس نمونه:

https://www.sso.com/auth/realms/sso/protocol/openid-connect/auth

پارامترهای ضروری:

  • client_id: شناسه کلاینت در سامانه SSO

  • redirect_uri: آدرس بازگشت پس از احراز هویت

  • response_type: باید مقدار code باشد

  • scope: شامل openid برای فعال‌سازی OIDC

  • state: رشته‌ای امن برای جلوگیری از حملات CSRF

نمونه کامل لینک:

https://www.sso.com/auth/realms/sso/protocol/openid-connect/auth?response_type=code&client_id=test&scope=openid%20profile&state=xyz&redirect_uri=http://localhost:4200

پس از احراز هویت موفق، کاربر به شکل زیر بازگردانده می‌شود:

http://localhost:4200/?state=xyz&code=abc123

🔐 مرحله سوم: دریافت Access Token از SSO

کلاینت باید با ارسال یک درخواست POST به Token Endpoint، توکن دریافت کند:

POST https://www.sso.com/auth/realms/sso/protocol/openid-connect/token

مقادیر مورد نیاز در 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 انجام شده باشد:

  1. فعال‌سازی Authorization Code Flow

  2. ثبت دقیق redirect URI در بخش آدرس‌های بازگشت معتبر

  3. تنظیم مقدار 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 استفاده می‌کنند، ولی در مرحله دریافت توکن، احراز هویت متفاوتی دارند.