> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# ما هو الدخول الموحد SSO؟ المصطلحات التي تحتاجها أولاً
- URL: https://arabroot.io/articles/ما-هو-الدخول-الموحد-sso-والمصطلحات/
- Published: 2026-10-25T18:33:04.000Z
- Updated: 2026-10-26T05:53:45.000Z
- Description: خريطة لمصطلحات الدخول الموحد SSO مع تجربة حقيقية تبين كيف تفتح جلسة واحدة في مزود الهوية تطبيقين، وماذا يبقى بعد الخروج.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, الأمن السيبراني, الاستضافة الذاتية, Keycloak

لنفرض أن لديك شركة تسويق رقمي في الرياض فيها خمسة وعشرون موظفاً، وتعمل على تسعة تطبيقات: البريد، وسيرفر Git لفريق التطوير، وقاعدة المعرفة Wiki، ونظام التذاكر، والمحادثة، ولوحة المراقبة، ومجلد الملفات المشترك، ونظام علاقات العملاء CRM، ونظام الموارد البشرية. وفي كل صباح أحد يصل إلى مسؤول تقنية المعلومات طلبان أو ثلاثة لإعادة تعيين كلمة مرور، وفي الشهر الماضي غادر مصمم الشركة فأغلق المسؤول حسابه في البريد وفي المحادثة، ونسي نظام الملفات المشترك الذي بقي يفتحه من بيته أسبوعين. ثم جاء العميل الأكبر بشرط جديد في العقد: مصادقة متعددة العوامل MFA لكل من يدخل إلى بيانات العميل. والمسؤول يعرف أن تسعة تطبيقات تعني تسعة إعدادات MFA مختلفة، بعضها لا يدعمه أصلاً.

هذا هو المكان الذي يبدأ فيه الحديث عن الدخول الموحد Single Sign-On واختصاراً SSO. وعندما يفتح المسؤول أول دليل لإعداده سوف يقابل في الصفحة الأولى IdP وSP وAssertion وRedirect URI وSSO Session وMFA وSCIM، وكأن الجميع يعرفها مسبقاً. وهذا المقال هو الخريطة التي تسبق كل الأدلة الأخرى في هذا المسار: نشرح فيه كل مصطلح مرة واحدة ومن أي طرف يأتي، ونتابع شركة التسويق وهي تنتقل من تسع صفحات دخول إلى صفحة واحدة، ثم نجرب أهم فكرة فيه بأيدينا، وهي أن جلسة واحدة في مزود الهوية تفتح لك كل التطبيقات، وأن الخروج منها لا يغلق كل شيء كما يظن الناس.

وفي هذا المقال سوف نتناول:

- لماذا لا تحل كلمة المرور الواحدة في كل مكان المشكلة، وما الفرق بين الدخول الموحد SSO وكلمة المرور الموحدة.
- أطراف الدخول الموحد: المستخدم، ومزود الهوية IdP، ومزود الخدمة SP، والدليل Directory، وكيف تبنى الثقة بينهم.
- الجلسات الثلاث: جلسة المزود وجلسة التطبيق والتوكنات، وهي أكثر نقطة يخطئ فيها من يبدأ.
- تجربة عملية مع Keycloak وcurl: دخول واحد لتطبيقين، ثم تسجيل الخروج وما يبقى بعده.
- المصادقة متعددة العوامل MFA، وتجهيز الحسابات Provisioning، والاتحاد Federation، ومخاطر وضع كل المفاتيح في مكان واحد.
- جدول بكل المصطلحات وأين تقرأ عن كل منها بالتفصيل.

## كلمة مرور لكل تطبيق، وما الذي جربته الفرق قبل SSO

لنفرض أن لديك فريقاً من عشرين شخصاً وثمانية تطبيقات مستضافة ذاتياً: البريد، وGitea، وWiki، ونظام التذاكر، والمحادثة، ومدير كلمات المرور، ولوحة المراقبة، ونظام الموارد البشرية. كل تطبيق يحفظ كلمة مرور كل موظف بطريقته، ولذلك لديك 160 كلمة مرور، وثماني صفحات دخول يمكن أن تتعرض لتخمين كلمات المرور Password Guessing، وثمانية أماكن يجب أن تغلقها في يوم مغادرة أي موظف. والحلول الأولى التي تجربها أغلب الفرق كما يلي:

- **كلمة مرور واحدة يتذكرها الموظف لكل التطبيقات:** وهذا ما يحدث تلقائياً عندما تكثر كلمات المرور، والمشكلة أن تسريب كلمة المرور من أضعف تطبيق يفتح الثمانية كلها، وهذا ما يسمى حشو بيانات الدخول Credential Stuffing.
- **مدير كلمات مرور Password Manager:** يحل مشكلة التذكر عند الموظف، وقد شرحناه في [إدارة كلمات المرور في المؤسسة](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D9%83%D9%84%D9%85%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D8%B1%D9%88%D8%B1-%D9%81%D9%8A-%D8%A7%D9%84%D9%85%D8%A4%D8%B3%D8%B3%D8%A9/)، ولكنه لا يغير شيئاً عند المؤسسة، فما زالت هناك ثمانية حسابات منفصلة وثماني سياسات وثمانية أماكن للإغلاق.
- **ربط كل التطبيقات بدليل مستخدمين Directory مثل LDAP:** وهنا تصبح كلمة المرور واحدة ومخزنة في مكان واحد، وتعطيل الحساب في الدليل يمنع الدخول إلى كل التطبيقات. وهذه خطوة كبيرة، ولكن لاحظ أن كل تطبيق ما زال يعرض صفحة دخول خاصة به، ويستقبل كلمة المرور نفسها ثم يمررها إلى الدليل، فإذا اخترق أحد التطبيقات فإن المخترق يرى كلمات المرور وهي تمر من خلاله، ولا يستطيع الدليل أن يطلب عاملاً ثانياً لأنه لا يرى إلا اسم المستخدم وكلمة المرور.

والحل الأخير له اسم يخلط الناس بينه وبين SSO، وهو كلمة المرور الموحدة أو Same Sign-On: الكلمة نفسها في كل مكان، ولكنك تكتبها في كل تطبيق. أما الدخول الموحد Single Sign-On فيعني أنك تكتبها مرة واحدة فقط، في مكان واحد، ولا يراها أي تطبيق أبداً.

والصورة التالية تبين ما يعنيه ذلك بأرقام الشركة نفسها:

![قبل SSO: موظف وتسعة تطبيقات هي البريد وGit وWiki والتذاكر والمحادثة والمراقبة والملفات وCRM والموارد البشرية، و25 موظفاً في 9 تطبيقات تعني 225 كلمة مرور وتسعة أماكن تغلق في يوم المغادرة، وبعد SSO: الموظف يدخل إلى مزود الهوية بكلمة مرور وMFA، والتطبيقات كلها تثق بالمزود، و25 كلمة مرور ومكان واحد للإغلاق، والتطبيق الذي لا يدعم SSO يوضع خلف Forward Auth](https://arabroot.io/content/images/2026/10/sso-basics-04-sprawl.webp)

225 كلمة مرور وتسعة أماكن للإغلاق، مقابل صفحة دخول واحدة ومكان واحد

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

## ما هو الدخول الموحد SSO؟

الدخول الموحد SSO هو أن تثبت هويتك مرة واحدة أمام طرف واحد موثوق هو مزود الهوية، ثم يقدم هذا الطرف لكل تطبيق تفتحه بعد ذلك رسالة موقعة تقول «هذه سارة، وقد تحققت منها قبل دقيقتين بكلمة المرور ورمز TOTP». والتطبيق لا يرى كلمة المرور، وإنما يتحقق من التوقيع على الرسالة ويثق بها.

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

![مخطط يبين المتصفح والمستخدمة سارة يميناً ومزود الهوية في الوسط ومعه الدليل Directory، والتطبيقات wiki وgit وmail يساراً، وخمس خطوات: تفتح Wiki، فيحولها إلى المزود، فتدخل مع MFA، فيرد المزود برسالة موقعة، ثم تفتح Git فتدخل دون كلمة مرور](https://arabroot.io/content/images/2026/10/sso-basics-01-actors.webp)

كلمة المرور تكتب في صفحة مزود الهوية فقط، والتطبيقات تستقبل رسالة موقعة

## الأطراف والمصطلحات التي سوف تقابلها في كل دليل

### الهوية Identity والدليل Directory

الهوية Identity هي سجل الشخص نفسه: اسم المستخدم، والبريد، والاسم الكامل، والمجموعات التي ينتمي إليها، وحالة الحساب نشط أو معطل. والمكان الذي تحفظ فيه هذه السجلات يسمى الدليل Directory، وقد يكون سيرفر LDAP مثل OpenLDAP أو Active Directory، وقد يكون قاعدة البيانات الداخلية لمزود الهوية نفسه. والفرق المهم هنا أن الدليل يجيب عن سؤال «من هم الموظفون؟»، أما مزود الهوية فيجيب عن سؤال «هل الذي أمامي الآن هو سارة فعلاً؟».

### مزود الهوية IdP

مزود الهوية Identity Provider واختصاراً IdP هو الخدمة التي تعرض صفحة الدخول، وتتحقق من كلمة المرور والعامل الثاني، وتحفظ جلسة المستخدم، ثم تصدر الرسائل الموقعة للتطبيقات. ومن أمثلته مفتوحة المصدر authentik وKeycloak وAuthelia وZITADEL وKanidm، ومن الخدمات التجارية Microsoft Entra ID وOkta وGoogle Workspace. وفي بعض الوثائق تجد اسماً آخر لنفس الدور، فمعيار OpenID Connect يسميه OpenID Provider واختصاراً OP، ومعيار OAuth يسمي الجزء الذي يصدر التوكنات خادم التفويض Authorization Server.

### مزود الخدمة SP والطرف المعتمد RP

مزود الخدمة Service Provider واختصاراً SP هو التطبيق الذي يريد أن يعرف من المستخدم، مثل Gitea أو Nextcloud أو Grafana. وهو اسم يأتي من عالم SAML، أما في OpenID Connect فاسمه الطرف المعتمد Relying Party واختصاراً RP، أي الطرف الذي يعتمد على المزود في معرفة المستخدم، وفي شاشات الإعداد تجده غالباً باسم Client أو Application. فإذا رأيت «أنشئ Client جديداً في Keycloak» أو «أضف Application في authentik» فالمقصود تسجيل التطبيق كمزود خدمة لدى المزود.

### البروتوكول Protocol: SAML أم OpenID Connect؟

البروتوكول هو اللغة التي يتحدث بها التطبيق مع مزود الهوية، وفي الدخول الموحد عبر الويب ستجد اثنين فقط في الواقع:

|                 | SAML 2.0                                           | OpenID Connect                                        |
| --------------- | -------------------------------------------------- | ----------------------------------------------------- |
| السنة           | 2005، من منظمة OASIS                               | 2014، من OpenID Foundation فوق OAuth 2.0              |
| شكل الرسالة     | وثيقة XML اسمها Assertion                          | توكن JSON اسمه ID Token بصيغة JWT                     |
| كيف تصل         | المتصفح يرسلها في نموذج POST إلى التطبيق           | التطبيق يستبدل كوداً قصيراً بالتوكنات من الخلف        |
| أين تجده غالباً | تطبيقات المؤسسات القديمة والخدمات السحابية الكبيرة | التطبيقات الحديثة والجوال وأغلب الأدوات مفتوحة المصدر |

وقد شرحنا OpenID Connect بالتفصيل مع تجربة كاملة في [شرح OAuth وOpenID Connect للمبتدئين](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-oauth-%D9%88-openid-connect-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)، ولـ SAML دليله الخاص في هذا المسار. والقاعدة العملية: إذا دعم التطبيق الاثنين فاختر OpenID Connect، وإذا لم يدعم إلا SAML فاستخدمه دون تردد، فكل مزودي الهوية المعروفين يدعمون الاثنين.

### الرسالة الموقعة: Assertion وID Token

الرسالة التي يحملها المتصفح من المزود إلى التطبيق هي قلب الدخول الموحد كله، وفي SAML اسمها Assertion، وفي OpenID Connect اسمها ID Token. وكلاهما يحمل الأشياء نفسها تقريباً: من المستخدم، ومن أصدر الرسالة Issuer، ولأي تطبيق صدرت Audience، ومتى تنتهي، ومتى تحقق المزود من المستخدم وبأي طريقة، ثم توقيع رقمي Digital Signature بمفتاح المزود الخاص. والتطبيق يرفض الرسالة إذا كان التوقيع غير صحيح، أو كانت صادرة لتطبيق آخر، أو انتهت مدتها، وهذه الفحوص الثلاثة هي ما يمنع شخصاً من أن يكتب رسالة بنفسه أو يعيد استخدام رسالة قديمة.

### الثقة المسبقة: Metadata وClient ID وRedirect URI

قبل أول دخول يجب أن يعرف كل طرف الآخر، وهذه الخطوة هي ما تفعله في شاشات الإعداد:

- **في SAML:** يتبادل الطرفان ملفين بصيغة XML اسمهما Metadata، وفي ملف المزود عنوان الدخول SSO URL وشهادة التوقيع، وفي ملف التطبيق معرفه Entity ID وعنوان استقبال الرسائل Assertion Consumer Service واختصاراً ACS.
- **في OpenID Connect:** تسجل التطبيق عند المزود فيعطيك معرف التطبيق Client ID وسره Client Secret، وتسجل عنده عنوان العودة Redirect URI الذي يقبل المزود أن يرسل إليه الكود، والتطبيق يقرأ كل شيء آخر من عنوان الاكتشاف Discovery الذي ينتهي بـ `/.well-known/openid-configuration`.

### من يبدأ الدخول: SP-initiated أم IdP-initiated؟

في الطريقة المعتادة يفتح المستخدم التطبيق أولاً، فيحوله التطبيق إلى المزود، وهذا ما يسمى الدخول الذي يبدؤه التطبيق SP-initiated. وفي الطريقة الثانية يفتح المستخدم لوحة المزود التي تعرض أيقونات التطبيقات ثم يضغط على أحدها، فيرسل المزود رسالة لم يطلبها التطبيق، وهذا ما يسمى IdP-initiated، وهو موجود في SAML فقط. ولاحظ أن الطريقة الثانية أضعف، والسبب أن التطبيق يستقبل رسالة لم يطلبها، فلا يستطيع أن يربطها بطلب خرج من عنده، ولذلك تفضل أغلب الأدلة أن تجعل أيقونات اللوحة روابط تفتح التطبيق، والتطبيق هو الذي يبدأ الدخول.

## الجلسات Sessions: ثلاث جلسات وليست جلسة واحدة

هذه هي النقطة التي يخطئ فيها أغلب من يبدأ، والسبب أن كلمة «الجلسة» تستخدم لثلاثة أشياء مختلفة. وإذا لم تكن تعرف كيف يتذكر الموقع المستخدم أصلاً عبر ملفات تعريف الارتباط Cookies فابدأ بـ [شرح الجلسات وCookies وJWT](https://arabroot.io/articles/%D8%A7%D9%84%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D9%88%D9%85%D9%84%D9%81%D8%A7%D8%AA-%D8%AA%D8%B9%D8%B1%D9%8A%D9%81-%D8%A7%D9%84%D8%A7%D8%B1%D8%AA%D8%A8%D8%A7%D8%B7-%D9%88-jwt-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)، ثم عد إلى هنا:

1. **جلسة المزود SSO Session:** ملف تعريف ارتباط على نطاق مزود الهوية، يتذكر به المزود أنك دخلت قبل قليل، وهي التي تجعل التطبيق الثاني يدخل دون أن تكتب كلمة المرور.
2. **جلسة التطبيق App Session:** بعد أن يستقبل التطبيق الرسالة الموقعة ينشئ جلسته الخاصة في ملف تعريف ارتباط على نطاقه، ومن تلك اللحظة لا يسأل المزود عن شيء حتى تنتهي جلسته.
3. **التوكنات Tokens:** في OpenID Connect يحصل التطبيق أيضاً على Access Token قصير العمر وRefresh Token يجدده به، والتجديد يمر على المزود في كل مرة.

![مخطط من ثلاثة أعمدة: جلسة المزود KEYCLOAK_SESSION تنتهي عند الخروج من المزود، وجلسة التطبيق wiki_session تبقى حتى تنتهي مدتها أو يصلها Back-channel Logout، والتوكنات حيث يعمل Access Token حتى وقت exp ويرفض Refresh Token فوراً برسالة Session not active](https://arabroot.io/content/images/2026/10/sso-basics-02-sessions.webp)

الخروج من المزود ينهي جلسة المزود، أما جلسات التطبيقات فلكل منها عمرها الخاص

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

## كم يجب أن تعيش كل جلسة؟

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

- **مهلة عدم النشاط Idle Timeout:** تنتهي الجلسة إذا لم يستخدمها صاحبها هذه المدة، فإذا ترك الموظف جهازه مفتوحاً وغادر المكتب لا تبقى جلسته صالحة طوال اليوم.
- **الحد الأقصى Max Lifespan:** تنتهي الجلسة بعد هذه المدة مهما كان النشاط، والقيمة الافتراضية في Keycloak عشر ساعات، وهو ما رأيناه في التجربة كقيمة `Max-Age=36000` في ملف تعريف الارتباط.

وهذا مثال لقرار الشركة، تبدأ منه وتعدله بحسب عملك:

| الجلسة               | المدة المقترحة                                       | السبب                                                   |
| -------------------- | ---------------------------------------------------- | ------------------------------------------------------- |
| جلسة المزود للموظفين | يوم عمل، مع مهلة عدم نشاط قصيرة                      | يدخل الموظف صباحاً مرة، وتنتهي جلسته إذا ترك جهازه      |
| جلسة المزود للمديرين | ساعات قليلة، وإعادة مصادقة للعمليات الحساسة          | جلسة المدير المسروقة تفتح لوحة المزود نفسها             |
| جلسة التطبيق         | أقصر من جلسة المزود، أو بحسب دعم Back-Channel Logout | هي المدة التي يبقى فيها المغادر داخل التطبيق بعد تعطيله |
| Access Token         | دقائق                                                | يتحقق منه التطبيق محلياً دون أن يسأل المزود             |
| Refresh Token        | بطول جلسة المزود                                     | كل تجديد يمر على المزود فيعرف إن انتهت الجلسة           |

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

## تجربة عملية: جلسة واحدة تفتح تطبيقين

سوف نشغل Keycloak كمزود هوية، وننشئ فيه مستخدمة اسمها `sara` وتطبيقين اسمهما `wiki` و`git`، ثم نستخدم `curl` مع ملف لحفظ ملفات تعريف الارتباط Cookie Jar ليقوم بدور المتصفح، حتى نرى كل تحويل وكل ملف تعريف ارتباط كما هو. ولا نحتاج إلى تطبيقين حقيقيين، لأن ما يهمنا هو ما يرسله المزود إلى عنوان العودة، و`curl` يرينا هذا العنوان دون أن يتبعه.

### الخطوة 1: تشغيل Keycloak وإنشاء المستخدمة والتطبيقين

نشغل Keycloak بوضع التطوير `start-dev` الذي يحفظ بياناته في قاعدة H2 داخلية، وهو مناسب للتجربة فقط وغير مناسب إطلاقاً للإنتاج:

```bash
docker run -d --name sso-lab-kc -p 8080:8080 \
  -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
  -e KC_BOOTSTRAP_ADMIN_PASSWORD='change-me-admin' \
  quay.io/keycloak/keycloak:26.8.1 start-dev
```

بعد أن يظهر في السجلات السطر `Keycloak 26.8.1 on JVM … started` ننشئ عالماً Realm باسم `demo`، وهو الحاوية المنطقية التي تضم المستخدمين والتطبيقات في Keycloak، ثم المستخدمة والتطبيقين عبر أداة الإدارة `kcadm.sh`:

```bash
K="docker exec sso-lab-kc /opt/keycloak/bin/kcadm.sh"
$K config credentials --server http://localhost:8080 --realm master --user admin --password 'change-me-admin'
$K create realms -s realm=demo -s enabled=true
$K create users -r demo -s username=sara -s email=sara@example.com -s firstName=Sara -s lastName=Ali -s emailVerified=true -s enabled=true
$K set-password -r demo --username sara --new-password 'Sara-Lab-2026'
$K create clients -r demo -s clientId=wiki -s secret=wiki-secret-lab -s 'redirectUris=["http://localhost:18801/callback"]' -s publicClient=false -s standardFlowEnabled=true
$K create clients -r demo -s clientId=git -s secret=git-secret-lab -s 'redirectUris=["http://localhost:18802/callback"]' -s publicClient=false -s standardFlowEnabled=true
```

في الإعداد أعلاه لاحظ التالي:

- كل تطبيق له Client ID وسر Client Secret وعنوان عودة واحد مسموح به، وهذه هي الثقة المسبقة التي ذكرناها.
- العنوانان `18801` و`18802` لا يعمل عليهما أي شيء، فنحن نريد أن نقرأ ما يرسله المزود إليهما فقط.
- إذا كنت تستخدم Git Bash على Windows فاكتب قبل الأوامر `export MSYS_NO_PATHCONV=1`، حتى لا يحول المسار `/opt/keycloak/…` إلى مسار Windows.

### الخطوة 2: Wiki يحولنا إلى المزود، وسارة تدخل مرة واحدة

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

```bash
IDP=http://localhost:8080/realms/demo/protocol/openid-connect
curl -s -c jar.txt -b jar.txt "$IDP/auth?client_id=wiki&response_type=code&scope=openid&redirect_uri=http://localhost:18801/callback&state=w1" -o form.html -w 'HTTP %{http_code}, login form: %{size_download} bytes\n'
ACTION=$(grep -o 'action="[^"]*"' form.html | head -1 | sed 's/action="//;s/"$//;s/&amp;/\&/g')
curl -s -c jar.txt -b jar.txt -D h1.txt -o /dev/null --data-urlencode username=sara --data-urlencode password='Sara-Lab-2026' "$ACTION"
grep -iE '^(HTTP|location)' h1.txt | cut -c1-110
grep -io 'set-cookie: [A-Z_]*=' h1.txt
```

والمخرج سوف يكون كما يلي:

```text
HTTP 200, login form: 6766 bytes
HTTP/1.1 302 Found
Location: http://localhost:18801/callback?state=w1&session_state=XpKFqAsv6Khdnd9qCTd7Qlw2&iss=http%3A%2F%2Floc
Set-Cookie: KC_RESTART=
Set-Cookie: KEYCLOAK_IDENTITY=
Set-Cookie: KEYCLOAK_SESSION=
```

لاحظ أن المزود أعاد المتصفح إلى عنوان Wiki ومعه كود قصير العمر وقيمة `session_state`، ووضع في المتصفح ملفين مهمين: `KEYCLOAK_IDENTITY` و`KEYCLOAK_SESSION`. وهذان الملفان هما جلسة المزود، وفي ردنا الحقيقي كانت مدة `KEYCLOAK_SESSION` هي `Max-Age=36000`، أي عشر ساعات، وهي القيمة الافتراضية للحد الأقصى لجلسة SSO في Keycloak كما يوضح [قسم المهلات Timeouts في دليل الإدارة](https://www.keycloak.org/docs/latest/server%5Fadmin/index.html?ref=arabroot.io#%5Ftimeouts).

### الخطوة 3: Git يحولنا إلى المزود نفسه، فلا تظهر صفحة الدخول

الآن تفتح سارة تطبيق Git، فيحولها هو الآخر إلى المزود بمعرفه وعنوان عودته. ونستخدم ملف ملفات تعريف الارتباط نفسه، تماماً كما يفعل المتصفح:

```bash
curl -s -c jar.txt -b jar.txt -D h2.txt -o /dev/null "$IDP/auth?client_id=git&response_type=code&scope=openid&redirect_uri=http://localhost:18802/callback&state=g1"
grep -iE '^(HTTP|location)' h2.txt | cut -c1-110
```

```text
HTTP/1.1 302 Found
Location: http://localhost:18802/callback?state=g1&session_state=XpKFqAsv6Khdnd9qCTd7Qlw2&iss=http%3A%2F%2Floc
```

وهذا هو الدخول الموحد كله في سطرين: لم يرد المزود بصفحة دخول (الرمز 200 في الخطوة السابقة)، وإنما رد مباشرة بالتحويل 302 إلى تطبيق Git ومعه كود جديد، لأنه وجد ملف `KEYCLOAK_SESSION` فعرف أن سارة دخلت قبل ثانيتين. ولاحظ أن `session_state` هي نفسها في الردين، أي أن التطبيقين يعتمدان على جلسة المزود نفسها.

### الخطوة 4: كل تطبيق يستبدل كوده بالتوكنات

الكود وحده لا يعني شيئاً، فكل تطبيق يرسله من الخلف إلى المزود مع سره، ويحصل على التوكنات. ونفعل ذلك للتطبيقين ثم نقرأ أهم حقول الـ ID Token:

```bash
code_of() { grep -i '^location' "$1" | sed 's/.*[?&]code=\([^&\r]*\).*/\1/' | tr -d '\r'; }
b64d() { local s=$(echo -n "$1" | tr '_-' '/+'); while [ $(( ${#s} % 4 )) -ne 0 ]; do s="$s="; done; echo -n "$s" | base64 -d 2>/dev/null; }
for app in wiki:18801 git:18802; do n=${app%%:*}; p=${app##*:}; f=h1.txt; [ $n = git ] && f=h2.txt
  curl -s "$IDP/token" -d grant_type=authorization_code -d client_id=$n -d client_secret=$n-secret-lab \
    -d code=$(code_of $f) -d redirect_uri=http://localhost:$p/callback > tok-$n.json
  idt=$(grep -o '"id_token":"[^"]*"' tok-$n.json | cut -d'"' -f4)
  echo "-- $n id_token:"; b64d "$(echo $idt | cut -d. -f2)" | tr ',' '\n' | grep -E '"(aud|sub|auth_time|sid|preferred_username|iat|exp)"'
done
```

```text
-- wiki id_token:
{"exp":1792955612
"iat":1792955312
"auth_time":1792955311
"aud":"wiki"
"sub":"ef3c77b7-31e8-499b-867f-f83d325d95bc"
"sid":"XpKFqAsv6Khdnd9qCTd7Qlw2"
"preferred_username":"sara"
-- git id_token:
{"exp":1792955613
"iat":1792955313
"auth_time":1792955311
"aud":"git"
"sub":"ef3c77b7-31e8-499b-867f-f83d325d95bc"
"sid":"XpKFqAsv6Khdnd9qCTd7Qlw2"
"preferred_username":"sara"
```

في المخرج أعلاه لاحظ التالي:

- `aud` مختلف في كل توكن، فتوكن Wiki صادر لـ Wiki فقط، وإذا حاول أحد أن يقدمه إلى Git فيجب أن يرفضه Git، وهذا هو فحص الجمهور Audience الذي ذكرناه.
- `sub` واحد في التوكنين، وهو المعرف الثابت للمستخدمة، وعلى التطبيق أن يربط حسابه به وليس بالبريد أو الاسم، لأن البريد قد يتغير.
- `auth_time` واحد في التوكنين (`1792955311`)، فهو وقت إدخال كلمة المرور الفعلي وليس وقت إصدار التوكن، ولذلك يستطيع التطبيق الحساس أن يقرر أن دخولاً قديماً لا يكفيه.
- `sid` هو معرف جلسة المزود، وهو نفسه في التوكنين، وسوف يستخدمه المزود لاحقاً ليخبر كل تطبيق بأن هذه الجلسة انتهت.
- الفرق بين `exp` و`iat` هو 300 ثانية، أي أن مدة الـ ID Token والـ Access Token هنا خمس دقائق، وهي القيمة الافتراضية في Keycloak.

ومن جهة المزود نرى الجلسة نفسها عبر واجهة الإدارة REST، وفيها التطبيقان:

```bash
$K get users/ef3c77b7-31e8-499b-867f-f83d325d95bc/sessions -r demo
```

```json
[ {
  "id" : "XpKFqAsv6Khdnd9qCTd7Qlw2",
  "username" : "sara",
  "userId" : "ef3c77b7-31e8-499b-867f-f83d325d95bc",
  "ipAddress" : "192.168.96.1",
  "start" : 1792955310000,
  "lastAccess" : 1792955313000,
  "rememberMe" : false,
  "clients" : {
    "dc672ad6-6ab8-46a7-bc89-e5cff58e5470" : "git",
    "78971e96-ba1c-4928-bfae-90793fbab54b" : "wiki"
  },
  "transientUser" : false
} ]
```

والصورة التالية من شاشة Sessions في لوحة إدارة Keycloak، وفيها الجلسة نفسها ومعها التطبيقان:

![شاشة Sessions في لوحة إدارة Keycloak للعالم demo، وفيها جلسة واحدة من نوع REGULAR للمستخدمة sara، وفي عمود Clients التطبيقان git وwiki](https://arabroot.io/content/images/2026/10/sso-basics-03-keycloak-sessions.webp)

جلسة واحدة في المزود، وتحتها كل التطبيقات التي دخلتها سارة بها

### الخطوة 5: نخرج من Wiki، فماذا يحدث لـ Git؟

الآن تخرج سارة من Wiki، والتطبيق يرسل طلب الخروج إلى المزود من الخلف بالـ Refresh Token الذي معه، فينهي المزود الجلسة كلها. بعد ذلك نسأل ثلاثة أسئلة من جهة Git: هل يستطيع أن يجدد توكنه؟ وماذا يقول المزود عن الـ Access Token الذي معه؟ وماذا يحدث إذا فتحت سارة Git مرة أخرى؟

```bash
RT=$(grep -o '"refresh_token":"[^"]*"' tok-wiki.json | cut -d'"' -f4)
curl -s -o /dev/null -w 'HTTP %{http_code}\n' "$IDP/logout" -d client_id=wiki -d client_secret=wiki-secret-lab -d refresh_token=$RT

RT2=$(grep -o '"refresh_token":"[^"]*"' tok-git.json | cut -d'"' -f4)
curl -s "$IDP/token" -d grant_type=refresh_token -d client_id=git -d client_secret=git-secret-lab -d refresh_token=$RT2; echo

AT2=$(grep -o '"access_token":"[^"]*"' tok-git.json | cut -d'"' -f4)
curl -s "$IDP/token/introspect" -d client_id=git -d client_secret=git-secret-lab -d token=$AT2; echo

curl -s -c jar.txt -b jar.txt -o /dev/null -w 'HTTP %{http_code}\n' "$IDP/auth?client_id=git&response_type=code&scope=openid&redirect_uri=http://localhost:18802/callback&state=g2"
```

والمخرج سوف يكون كما يلي:

```text
HTTP 204
{"error":"invalid_grant","error_description":"Session not active"}
{"active":false}
HTTP 200
```

في المخرج أعلاه لاحظ التالي:

- الرد `204` يعني أن المزود أنهى الجلسة، ولم يعد في المتصفح ما يفتح التطبيقات تلقائياً، فالطلب الأخير من Git رجع بصفحة الدخول (الرمز 200) بدلاً من التحويل 302.
- تجديد التوكن في Git فشل برسالة `Session not active`، لأن التجديد يمر على المزود دائماً.
- عندما سأل Git المزود عن الـ Access Token عبر نقطة الفحص Introspection المعرفة في [RFC 7662](https://datatracker.ietf.org/doc/html/rfc7662?ref=arabroot.io) كان الرد `"active":false`. ولكن لاحظ أن أغلب التطبيقات لا تسأل المزود أصلاً، وإنما تتحقق من توقيع الـ JWT ومن `exp` بنفسها، وفي تجربتنا كان `exp` لتوكن Git هو `1792955613` ووقت الخروج `1792955427`، أي أن التطبيق الذي يتحقق محلياً سوف يقبل التوكن ثلاث دقائق أخرى بعد الخروج.
- والأهم من ذلك جلسة التطبيق نفسه: لو كان Git تطبيقاً حقيقياً لكان قد أنشأ جلسته الخاصة عند الدخول، وهذه الجلسة لا يعرف بها المزود، فتبقى مفتوحة حتى تنتهي مدتها، إلا إذا كان التطبيق يدعم إشعار الخروج من الخلف الذي نشرحه الآن.

## الخروج الموحد Single Logout: لماذا هو أصعب من الدخول؟

الدخول الموحد سهل لأن المتصفح يمر على المزود في كل دخول، أما الخروج فيحتاج المزود أن يخبر كل تطبيق فتحت فيه جلسة، وهذا ما يسمى الخروج الموحد Single Logout واختصاراً SLO. وفي OpenID Connect ثلاثة معايير لذلك:

- [RP-Initiated Logout](https://openid.net/specs/openid-connect-rpinitiated-1%5F0.html?ref=arabroot.io): التطبيق يحول المستخدم إلى عنوان الخروج في المزود، وهذا ينهي جلسة المزود فقط.
- [Front-Channel Logout](https://openid.net/specs/openid-connect-frontchannel-1%5F0.html?ref=arabroot.io): المزود يفتح في المتصفح صفحة خروج كل تطبيق في إطارات مخفية iframes، وهذه الطريقة تفشل كثيراً اليوم لأن المتصفحات تحجب ملفات تعريف الارتباط داخل الإطارات القادمة من نطاق آخر.
- [Back-Channel Logout](https://openid.net/specs/openid-connect-backchannel-1%5F0.html?ref=arabroot.io): المزود يرسل من سيرفره إلى سيرفر كل تطبيق رسالة موقعة اسمها Logout Token تحمل `sid`، فينهي التطبيق الجلسة المرتبطة بها، وهي الطريقة الموثوقة لأنها لا تعتمد على المتصفح.

وفي SAML يوجد Single Logout أيضاً، ولكن دعمه في التطبيقات أضعف بكثير. لذلك عند اختيار تطبيق للمؤسسة اسأل: هل يدعم Back-Channel Logout؟ وإذا لم يدعمه فاجعل مدة جلسته قصيرة، ساعات وليس أسابيع، والسبب أن مدة جلسة التطبيق هي المدة التي يبقى فيها الموظف المغادر داخل التطبيق بعد أن تعطله في المزود.

والصورة التالية تجمع الطرق الثلاث، ومن يخبر من في كل طريقة:

![ثلاث طرق للخروج: RP-Initiated حيث يحول التطبيق المتصفح إلى /logout فتنتهي جلسة المزود والتطبيقات الأخرى لا تعرف، وFront-Channel حيث يزور المتصفح كل تطبيق في iframe ويفشل عندما يحجب المتصفح ملفات الطرف الثالث، وBack-Channel حيث يرسل سيرفر المزود Logout Token يحمل sid عبر POST إلى wiki وgit وmail ولا يعتمد على المتصفح ولكن يحتاج تطبيقاً يدعمه](https://arabroot.io/content/images/2026/10/sso-basics-05-logout.webp)

الطريقة الموثوقة هي التي لا تعتمد على المتصفح، وهي Back-Channel

وفي شركة التسويق كان السؤال العملي: أي التطبيقات التسعة تدعم Back-Channel Logout؟ والإجابة تجدها في توثيق كل تطبيق، وغالباً تكون قلة منها، لذلك الأنسب أن تكون جلسات التطبيقات الحساسة، مثل CRM ونظام الموارد البشرية، قصيرة لا تتجاوز ساعات، وأن تكون المغادرة إجراء يغلق الحساب في المزود ثم يعطله في التطبيقات التي تحمل بيانات العملاء، كما شرحنا في مقال SCIM.

## المصادقة متعددة العوامل MFA: مكانها في المزود

من أكبر فوائد الدخول الموحد أن المصادقة متعددة العوامل Multi-Factor Authentication واختصاراً MFA تفرض في مكان واحد، فبدلاً من أن تبحث هل يدعم كل تطبيق رموز TOTP، تفرضها في المزود فتصبح كل التطبيقات محمية بها. وقد شرحنا فرضها في [دليل تثبيت authentik](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-authentik-%D9%84%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%88%D8%AD%D8%AF/#mfa)، والطريقة الأقوى ضد التصيد Phishing هي [مفاتيح المرور Passkeys](https://arabroot.io/articles/%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%AF%D9%88%D9%86-%D9%83%D9%84%D9%85%D8%A9-%D9%85%D8%B1%D9%88%D8%B1-passkeys-%D9%88-fido2/). وهناك ثلاثة مصطلحات مرتبطة سوف تقابلها:

- **مستوى المصادقة acr وطرقها amr:** حقلان في الـ ID Token يخبران التطبيق كيف تحقق المزود من المستخدم، فـ `amr` يحمل قيماً مثل `pwd` و`otp` و`hwk` المعرفة في [RFC 8176](https://www.rfc-editor.org/rfc/rfc8176?ref=arabroot.io)، و`acr` يحمل اسم المستوى الذي يتفق عليه الطرفان.
- **رفع مستوى المصادقة Step-up Authentication:** التطبيق يقبل الدخول بكلمة المرور لقراءة الصفحات، ولكنه يطلب من المزود مستوى أعلى قبل عملية حساسة مثل تحويل مالي، وقد وحد معيار [RFC 9470](https://datatracker.ietf.org/doc/html/rfc9470?ref=arabroot.io) طريقة طلب ذلك.
- **إعادة المصادقة Re-authentication:** التطبيق يرسل `max_age` أو `prompt=login` فيطلب المزود كلمة المرور من جديد حتى لو كانت جلسته مفتوحة، ويتأكد التطبيق من ذلك عبر `auth_time` الذي رأيناه في التجربة.

وفي السعودية، إذا كانت جهتك ضمن نطاق [الضوابط الأساسية للأمن السيبراني ECC](https://arabroot.io/articles/%D8%A7%D9%84%D8%B6%D9%88%D8%A7%D8%A8%D8%B7-%D8%A7%D9%84%D8%A7%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D9%84%D8%A7%D9%85%D9%86-%D8%A7%D9%84%D8%B3%D9%8A%D8%A8%D8%B1%D8%A7%D9%86%D9%8A-nca-ecc-%D8%A8%D9%84%D8%BA%D8%A9-%D8%A8%D8%B3%D9%8A%D8%B7%D8%A9/) فإن الضابط 2-2-3-2 في [وثيقة ECC-2:2024](https://cdn.nca.gov.sa/api/files/public/upload/29a9e86a-595f-4af9-8db5-88715a458a14%5FECC-2-2024---NCA.pdf?ref=arabroot.io) يطلب التحقق متعدد العوامل للدخول عن بعد Remote Access وللحسابات ذات الصلاحيات الهامة Privileged Accounts، مع تحديد العوامل وعددها بحسب تقييم أثر فشل المصادقة أو تجاوزها، كما في [النسخة الإنجليزية](https://cdn.nca.gov.sa/api/files/public/upload/86e09090-44e4-481f-bc28-355673607654%5FECC--2024-EN.pdf?ref=arabroot.io). والدخول الموحد هو أسهل طريقة لتحقيق ذلك، لأنك تفرضه مرة واحدة في المزود ثم تثبت للمدقق أن كل تطبيق يمر عليه.

## تجهيز الحسابات Provisioning: الدخول شيء، والحساب شيء آخر

الدخول الموحد يجيب عن «من يدخل الآن؟»، ولكن الحساب نفسه يعيش داخل كل تطبيق، ومعه مجموعاته وملفاته ورموزه Tokens. وهناك ثلاث طرق لوصول الحساب إلى التطبيق:

| الطريقة                      | كيف تعمل                                                    | ما ينقصها                                                      |
| ---------------------------- | ----------------------------------------------------------- | -------------------------------------------------------------- |
| الإنشاء عند أول دخول JIT     | التطبيق ينشئ الحساب عندما تصله أول رسالة موقعة عن المستخدم  | لا يعطل الحساب عند المغادرة، لأن من غادر لن يدخل مرة أخرى      |
| المزامنة من الدليل LDAP Sync | التطبيق يسحب المستخدمين والمجموعات من LDAP دورياً           | التغيير يصل في المزامنة التالية، وبعض التطبيقات لا تعطل من حذف |
| SCIM                         | المزود يرسل الإنشاء والتعديل والتعطيل إلى التطبيق فور حدوثه | أغلب التطبيقات مفتوحة المصدر لا تدعمه بعد                      |

وقد خصصنا لهذه الفجوة مقالاً كاملاً مع تجربة عملية في [ما هو SCIM؟](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-scim-%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D8%B3%D8%A7%D8%A8%D8%A7%D8%AA-%D8%AA%D9%84%D9%82%D8%A7%D8%A6%D9%8A%D8%A7/)، ولدورة حياة الحساب من التعيين إلى المغادرة مقال [دورة حياة حساب الموظف JML](https://arabroot.io/articles/%D8%AF%D9%88%D8%B1%D8%A9-%D8%AD%D9%8A%D8%A7%D8%A9-%D8%AD%D8%B3%D8%A7%D8%A8-%D8%A7%D9%84%D9%85%D9%88%D8%B8%D9%81-jml/).

## الاتحاد Federation والوسيط Identity Brokering

الاتحاد Federation هو أن يثق مزود هوية بمزود هوية آخر. فإذا كانت شركتك تعمل مع جهة شريكة لها مزود هويتها الخاص، فبدلاً من أن تنشئ حسابات لموظفيها عندك، تربط مزودك بمزودهم، فيدخل موظفوهم بحساباتهم ويصلك منهم الاسم والبريد فقط. ومن الحالات الشائعة أيضاً الدخول بحساب Google أو Microsoft، وهنا يقوم مزودك بدور الوسيط Identity Broker: يحول المستخدم إلى Google، ثم يستقبل الرد ويصدر رسالته الخاصة لتطبيقاتك، فتبقى التطبيقات مربوطة بمزود واحد هو مزودك. وقد طبقنا ذلك في [تسجيل الدخول بحساب Google في authentik](https://arabroot.io/articles/%D8%AA%D8%B3%D8%AC%D9%8A%D9%84-%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A8%D8%AD%D8%B3%D8%A7%D8%A8-google-%D9%81%D9%8A-authentik/).

![متعاقد من وكالة شريكة يملك حساب Google فقط، يدخل عبر مزودك authentik الذي يقبل الدخول من Google ثم يصدر رسالته هو ويطبق مجموعاته وMFA، والتطبيقات Wiki وGit والتذاكر والملفات تستقبل رسالة من مزودك فقط، ولماذا لا تربط التطبيقات بـ Google مباشرة: لأن المجموعات والصلاحيات تبقى عندك وتغلق المتعاقد من مكان واحد وتستبدل Google دون أن تلمس التطبيقات، والاتحاد Federation نفس الفكرة بين مؤسستين](https://arabroot.io/content/images/2026/10/sso-basics-06-broker.webp)

التطبيقات لا تعرف Google، وإنما تعرف مزودك فقط

ولنفرض أن شركة التسويق تعمل مع وكالة إنتاج فيديو شريكة، ومصمموها يحتاجون إلى مجلد الملفات المشترك وقاعدة المعرفة شهرين في السنة. فبدلاً من حسابات جديدة بكلمات مرور جديدة، يجعل المسؤول مزود الهوية يقبل الدخول بحساباتهم في Google، ويضعهم في مجموعة `partners` لا تفتح إلا التطبيقين، ويجعل لعضويتهم تاريخ انتهاء. وعندما ينتهي العقد يكفي أن تفرغ المجموعة، دون أن يلمس أي تطبيق.

## كل المفاتيح في مكان واحد: مخاطر الدخول الموحد

الدخول الموحد يقلل عدد الأبواب، ولكنه يجعل باباً واحداً أهم من كل الأبواب، ولذلك عامل مزود الهوية كأنه أهم سيرفر عندك:

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

📌

في أكتوبر 2023 أعلنت Okta، وهي من أكبر مزودي الهوية التجاريين، أن مهاجماً دخل نظام الدعم الفني لديها بين 28 سبتمبر و17 أكتوبر 2023 عبر حساب خدمة Service Account كانت بياناته محفوظة في حساب Google شخصي لأحد الموظفين، فنزل ملفات من 134 عميلاً، بعضها ملفات HAR التي يسجل فيها المتصفح الطلبات ومعها توكنات الجلسات Session Tokens، واستخدمها ليختطف جلسات حقيقية لخمسة عملاء. ومن الإصلاحات التي أعلنتها الشركة في [تقرير السبب الجذري](https://sec.okta.com/articles/2023/11/unauthorized-access-oktas-support-case-management-system-root-cause?ref=arabroot.io) ربط جلسة المدير بموقع الشبكة، فإذا تغير الموقع طلبت المصادقة من جديد. والدرس هنا أن الجلسة المسروقة لا تحتاج إلى كلمة المرور ولا إلى MFA، فاحم ملفات الجلسات كما تحمي كلمات المرور، ولا ترسل ملف HAR لأحد قبل أن تحذف منه ملفات تعريف الارتباط والتوكنات.

## ماذا يحدث عندما يتوقف مزود الهوية؟

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

- **جلسات التطبيقات المفتوحة تستمر:** من فتح البريد صباحاً يبقى يعمل حتى تنتهي جلسة التطبيق، لأن التطبيق لا يسأل المزود عن كل طلب.
- **التجديد يفشل:** التطبيقات التي تجدد التوكنات كل بضع دقائق تخرج مستخدميها بعد أول تجديد، كما فشل تجديد Git في الخطوة 5 برسالة `Session not active`، وهذا ما يجعل التوقف يظهر بالتدريج.
- **الدخول الجديد مستحيل:** كل من أغلق متصفحه أو فتح تطبيقاً جديداً يتوقف عند صفحة خطأ.

لذلك يحتاج مزود الهوية إلى ثلاثة أشياء لا تحتاجها أغلب التطبيقات: مراقبة تنبهك قبل أن يمتلئ القرص أو تتوقف قاعدة البيانات، ونسخة احتياطية مجربة تستعاد في دقائق، وحساب طوارئ Break-glass يدخل إلى السيرفر وإلى لوحة إدارة المزود دون أن يمر بالمزود نفسه، وقد خصصنا له مقالاً كاملاً مع تجربة في [الوصول المؤقت وحساب الطوارئ](https://arabroot.io/articles/%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D8%A4%D9%82%D8%AA-jit-%D9%88%D8%AD%D8%B3%D8%A7%D8%A8-%D8%A7%D9%84%D8%B7%D9%88%D8%A7%D8%B1%D8%A6-break-glass/).

## كيف تنتقل الشركة إلى SSO خطوة خطوة؟

لا يربط المسؤول التطبيقات التسعة في يوم واحد، لأن تطبيقاً واحداً يتعطل فيه الدخول يعني أن قسماً كاملاً لا يعمل. وهذه خطة تنفع أي شركة صغيرة:

1. **الجرد:** جدول بالتطبيقات، وما يدعمه كل منها: OpenID Connect أم SAML أم LDAP فقط أم لا شيء، ومن يملك كل تطبيق، وما البيانات الحساسة فيه. وفي شركة كهذه تجد عادة أغلب التطبيقات الحديثة تدعم OIDC، وبعض الخدمات القديمة SAML فقط، وتطبيقاً أو اثنين يدعمان LDAP، ولوحة قديمة لا تدعم شيئاً.
2. **المزود أولاً:** تثبيت مزود الهوية، ونقل المستخدمين إليه، وفرض MFA على الجميع قبل ربط أي تطبيق، حتى يتعود الموظفون على صفحة الدخول الجديدة والعامل الثاني.
3. **تطبيق تجريبي:** قاعدة المعرفة Wiki أولاً، لأن توقفها لساعة لا يوقف العمل، ويستخدمها الجميع فتظهر المشكلات بسرعة.
4. **التطبيقات الحساسة:** البريد ونظام الملفات وCRM، مع مدة جلسة قصيرة في كل منها، لأنها التي يطلب العميل حمايتها.
5. **التطبيقات القديمة:** التطبيق الذي يدعم LDAP فقط يقرأ المستخدمين عبر LDAP، واللوحة التي لا تدعم شيئاً توضع خلف صفحة دخول المزود عبر [Forward Auth](https://arabroot.io/articles/%D8%AD%D9%85%D8%A7%D9%8A%D8%A9-%D8%A3%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-authentik-forward-auth/).
6. **إغلاق الأبواب القديمة:** بعد أن يعمل الدخول الموحد في كل تطبيق، تعطل كلمات المرور المحلية فيه، إلا حساب مدير طوارئ واحد، حتى لا يبقى طريق جانبي يتجاوز MFA.

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

## أخطاء شائعة

| الخطأ                                      | لماذا يهم                                                 |
| ------------------------------------------ | --------------------------------------------------------- |
| تعطيل الحساب في المزود فقط                 | جلسات التطبيقات والرموز Tokens تبقى، كما رأينا في التجربة |
| جلسة تطبيق ثلاثين يوماً                    | المزود يقرر الدخول الأول فقط                              |
| ترك الدخول بكلمة المرور المحلية مفعلاً     | باب جانبي يتجاوز MFA                                      |
| ربط الحساب في التطبيق بالبريد بدلاً من sub | البريد يتغير أو يعاد استخدامه لموظف جديد                  |
| Redirect URI عامة بنجمة                    | المزود قد يرسل الكود إلى عنوان لا تملكه                   |
| لوحة المزود خلف المزود دون حساب طوارئ      | لا أحد يدخل لإصلاحه عندما يتوقف                           |

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

## جدول المصطلحات

وفيما يلي كل المصطلحات التي مرت في المقال في مكان واحد، لترجع إليه عندما تقرأ أي دليل إعداد:

| المصطلح                                | معناه باختصار                                                             |
| -------------------------------------- | ------------------------------------------------------------------------- |
| الدخول الموحد SSO                      | تثبت هويتك مرة واحدة أمام مزود الهوية، فتفتح كل التطبيقات المربوطة به     |
| كلمة المرور الموحدة Same Sign-On       | كلمة المرور نفسها من الدليل، ولكنك تكتبها في كل تطبيق                     |
| مزود الهوية IdP أو OP                  | الخدمة التي تتحقق من المستخدم وتصدر الرسائل الموقعة                       |
| مزود الخدمة SP أو RP أو Client         | التطبيق الذي يثق بمزود الهوية                                             |
| الدليل Directory                       | مخزن المستخدمين والمجموعات، مثل LDAP                                      |
| Assertion                              | رسالة SAML الموقعة بصيغة XML                                              |
| ID Token                               | رسالة OpenID Connect الموقعة بصيغة JWT                                    |
| Metadata وEntity ID وACS               | بيانات الثقة المسبقة في SAML                                              |
| Client ID وClient Secret وRedirect URI | بيانات الثقة المسبقة في OpenID Connect                                    |
| جلسة المزود SSO Session                | ما يجعل التطبيق الثاني يدخل دون كلمة مرور                                 |
| جلسة التطبيق App Session               | جلسة كل تطبيق الخاصة بعد أن يستقبل الرسالة                                |
| الخروج الموحد SLO                      | إنهاء الجلسة في المزود وفي كل التطبيقات، والموثوق منه Back-Channel Logout |
| المصادقة متعددة العوامل MFA            | عامل ثاني بعد كلمة المرور، يفرض مرة واحدة في المزود                       |
| acr وamr                               | حقول تخبر التطبيق بمستوى المصادقة وطريقتها                                |
| JIT Provisioning                       | إنشاء الحساب في التطبيق عند أول دخول                                      |
| SCIM                                   | معيار يرسل به المزود إنشاء الحسابات وتعطيلها إلى التطبيقات                |
| الاتحاد Federation والوسيط Broker      | مزود يثق بمزود آخر، مثل الدخول بحساب Google                               |

## من أين تبدأ؟

إذا كنت تبدأ من الصفر وتريد مزود هوية لفريق صغير أو متوسط فابدأ بـ authentik، فقد شرحنا تثبيته وربطه بالتطبيقات خطوة خطوة، وإذا كانت تطبيقاتك لا تدعم OIDC ولا SAML فضع أمامها صفحة دخول المزود عبر Forward Auth. والمقالات التالية تكمل هذه الخريطة:

[![](https://arabroot.io/content/images/2026/10/authentik-cover-cover-1.webp)دليلتثبيت authentik للدخول الموحد SSO إلى تطبيقاتككيف تثبت authentik حتى يدخل كل موظف إلى تطبيقات الفريق بحساب واحد، مع فرض المصادقة الثنائية على الجميع.](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-authentik-%D9%84%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%88%D8%AD%D8%AF/)[![](https://arabroot.io/content/images/2026/10/authentik-forward-auth-cover-cover.webp)دليلكيف تحمي أي تطبيق ويب بصفحة دخول authentik عبر Forward Authكيف تضع صفحة دخول authentik مع المصادقة الثنائية أمام أي أداة داخلية دون أن تعدل في التطبيق نفسه.](https://arabroot.io/articles/%D8%AD%D9%85%D8%A7%D9%8A%D8%A9-%D8%A3%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-authentik-forward-auth/)[![](https://arabroot.io/content/images/2026/10/oauth-oidc-cover-cover.webp)دليلشرح OAuth وOpenID Connect للمبتدئينلماذا لا يجب أن يعرف أي تطبيق كلمة مرورك، وكيف يحل OAuth ذلك بتوكنات محدودة، وكيف يضيف OpenID Connect الدخول الموحد.](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-oauth-%D9%88-openid-connect-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/saml-cover-cover.webp)دليلSAML للمبتدئين: متى ما زالت المؤسسات تحتاجه؟نشرح SAML بتجربة حقيقية نرى فيها الـ Assertion كما يحمله المتصفح، ثم نعدله ونسرقه ونؤخره لنرى كيف يرفضه التطبيق.](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-saml-%D9%84%D9%84%D9%85%D8%A8%D8%AA%D8%AF%D8%A6%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/scim-cover-cover.webp)دليلما هو SCIM؟ إدارة حسابات الموظفين تلقائياً في كل تطبيقاتكالدخول الموحد SSO يمنع الموظف المغادر من الدخول لكن حساباته تبقى نشطة، وSCIM ينشئ الحسابات ويعطلها في كل تطبيق تلقائياً.](https://arabroot.io/articles/%D9%85%D8%A7-%D9%87%D9%88-scim-%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AD%D8%B3%D8%A7%D8%A8%D8%A7%D8%AA-%D8%AA%D9%84%D9%82%D8%A7%D8%A6%D9%8A%D8%A7/)[![](https://arabroot.io/content/images/2026/10/ldap-directory-cover-cover.webp)دليلLDAP ودليل المستخدمين: كيف تعرف التطبيقات من هو المستخدم؟نبني دليل مستخدمين على OpenLDAP ونرى بمخرجات ldapsearch الحقيقية كيف تتحقق التطبيقات من كلمة المرور والمجموعات، وأين يخطئ أغلب من يبدأ.](https://arabroot.io/articles/%D8%B4%D8%B1%D8%AD-ldap-%D9%88%D8%AF%D9%84%D9%8A%D9%84-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D8%AE%D8%AF%D9%85%D9%8A%D9%86/)[![](https://arabroot.io/content/images/2026/10/passkeys-cover-cover.webp)دليلالدخول دون كلمة مرور: شرح Passkeys وWebAuthnلماذا لا تحميك رموز SMS وTOTP من التصيد الحديث، وكيف تحل Passkeys المشكلة بمفتاح خاص لا يغادر جهازك.](https://arabroot.io/articles/%D8%A7%D9%84%D8%AF%D8%AE%D9%88%D9%84-%D8%AF%D9%88%D9%86-%D9%83%D9%84%D9%85%D8%A9-%D9%85%D8%B1%D9%88%D8%B1-passkeys-%D9%88-fido2/)[![](https://arabroot.io/content/images/2026/10/iam-pam-cover-cover.webp)دليلإدارة الهوية والوصول IAM والوصول المميز PAMمن يملك صلاحية root على سيرفراتك ومنذ متى، وكيف تضبط حسابات المديرين بصلاحيات مؤقتة وجلسات مسجلة.](https://arabroot.io/articles/%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%87%D9%88%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-iam-%D9%88%D8%A7%D9%84%D9%88%D8%B5%D9%88%D9%84-%D8%A7%D9%84%D9%85%D9%85%D9%8A%D8%B2-pam/)

## الخلاصة

- الدخول الموحد SSO يعني أن كلمة المرور تكتب في صفحة مزود الهوية فقط، والتطبيقات تستقبل رسالة موقعة، وهذا يختلف عن كلمة المرور الموحدة من LDAP التي تكتبها في كل تطبيق.
- الأطراف أربعة: المستخدم ومتصفحه، ومزود الهوية IdP، والتطبيقات SP أو RP، والدليل Directory خلف المزود. والثقة بينهم تبنى مسبقاً بالـ Metadata في SAML أو Client ID وRedirect URI في OIDC.
- هناك ثلاث جلسات: جلسة المزود التي تفتح التطبيقات دون كلمة مرور، وجلسة كل تطبيق، والتوكنات. وفي تجربتنا مع Keycloak 26.8.1 فتحت جلسة واحدة تطبيقين بنفس `sid`، وبعد الخروج رفض المزود تجديد التوكن فوراً، بينما بقي الـ Access Token صالحاً محلياً حتى `exp`.
- الخروج الموحد الموثوق هو Back-Channel Logout، وإذا لم يدعمه التطبيق فاجعل مدة جلسته قصيرة.
- افرض MFA مرة واحدة في المزود، والحسابات داخل التطبيقات تحتاج إلى SCIM أو مزامنة من الدليل حتى تغلق عند المغادرة.
- مزود الهوية أهم سيرفر عندك: احم جلساته ومديريه، وجهز نسخه الاحتياطي وحساب الطوارئ قبل أن تحتاجهما.

## سجل التحديثات

- أكتوبر 2026: كتابة المقال، وتنفيذ تجربة الجلسة الواحدة لتطبيقين على Keycloak 26.8.1.
- أكتوبر 2026: توسيع المقال بقصة شركة التسويق، وأقسام عن مدة الجلسات وتوقف مزود الهوية وخطة الانتقال والأخطاء الشائعة، وثلاث صور جديدة.