> For the complete documentation index, see [llms.txt](https://docs.chamilo.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chamilo.org/3.x/ar/dlyl-alidarh/admin-guide/authentication/azure-entra-id.md).

# Azure Entra ID

أعادت Microsoft تسمية Azure Active Directory (Azure AD) إلى **Microsoft Entra ID** في عام 2023 — فهما الخدمة نفسها، وما زال رمز Chamilo وإعداداته يشيران إليها باسم `azure`. تغطي هذه الصفحة الأجزاء الخاصة بـ Azure في التكامل: تسجيل التطبيق، وتعيين الأدوار استنادًا إلى المجموعات، والمصادقة بالشهادة، وأوامر مزامنة المستخدمين/المجموعات المخصصة. للاطلاع على مفاتيح الإعداد المشتركة بين كل الموفرين (`enabled` و`title` و`allow_create_new_users` وما إلى ذلك) وعلى البنية العامة لـ `authentication.yaml`، انظر [OAuth2](/3.x/ar/dlyl-alidarh/admin-guide/authentication/oauth2.md).

## تسجيل Chamilo في Microsoft Entra ID

1. في مركز إدارة Entra، أنشئ **تسجيل تطبيق** (App registration) لـ Chamilo.
2. عيّن عنوان إعادة التوجيه URI (نوع المنصة **Web**) إلى:

   ```
   https://your-chamilo-url/connect/azure/check
   ```
3. سجّل **معرّف التطبيق (العميل)** و**معرّف الدليل (المستأجر)** — ستحتاج إليهما معًا.
4. ضمن **Certificates & secrets**، أنشئ سر عميل أو ارفع شهادة (انظر [المصادقة بالشهادة](#certificate-authentication) أدناه).
5. ضمن **API permissions**، أضف أذونات Microsoft Graph أدناه وامنح موافقة المسؤول.

| الإذن                                      | النوع       | مطلوب من أجل                                          |
| ------------------------------------------ | ----------- | ----------------------------------------------------- |
| `User.Read`                                | Delegated   | تسجيل الدخول الأساسي                                  |
| `GroupMember.Read.All`                     | Delegated   | تعيين الأدوار استنادًا إلى المجموعات عند تسجيل الدخول |
| `User.Read.All`                            | Application | `app:azure-sync-users`                                |
| `GroupMember.Read.All` أو `Group.Read.All` | Application | `app:azure-sync-users` و `app:azure-sync-usergroups`  |

تتطلب أذونات التطبيق موافقة المسؤول وتُستخدم فقط من أوامر المزامنة في وحدة التحكم (عبر منحة `client_credentials`)، ولا تُستخدم أبدًا عند تسجيل دخول مستخدم تفاعلي.

## الإعداد الأساسي

```yaml
authentication:
  1:
    oauth2:
      azure:
        enabled: true
        title: "Sign in with Microsoft"
        client_id: "<application-client-id>"
        client_secret: "<client-secret>"
        tenant: "<tenant-id>"
        url_login: "https://login.microsoftonline.com"
        path_authorize: "/<tenant-id>/oauth2/v2.0/authorize"
        path_token: "/<tenant-id>/oauth2/v2.0/token"
        url_api: "https://graph.microsoft.com"
        allow_create_new_users: true
        allow_update_user_info: true
```

### متعدد المستأجرين مقابل مستأجر واحد

يجب أن تطابق قيمة `tenant` كيفية تعيين «أنواع الحسابات المدعومة» في تسجيل التطبيق:

* معرّف GUID لمستأجر محدد — مستأجر واحد، يمكن لحسابات تلك المؤسسة فقط تسجيل الدخول
* `organizations` — أي مستأجر Entra ID
* `common` — أي مستأجر Entra ID بالإضافة إلى حسابات Microsoft الشخصية

## سمات المستخدم المطلوبة

يجب أن يكون لدى كل مستخدم Entra ID يحتاج إلى تسجيل الدخول إلى Chamilo الحقلان `mail` و`mailNickname` معبّأين — يُلقي تسجيل الدخول خطأً إذا كان أي منهما فارغًا (إلى جانب معرّف كائن Entra غير القابل للتغيير، الموجود دائمًا). تعيين الحقول من Microsoft Graph إلى Chamilo **ثابت** لـ Azure (بخلاف موفر OAuth2 العام الذي يتيح لك تكوين تعيين الحقول):

| حقل Chamilo       | مصدر Microsoft Graph                                                                      |
| ----------------- | ----------------------------------------------------------------------------------------- |
| الاسم الأول       | `givenName`                                                                               |
| اسم العائلة       | `surname`                                                                                 |
| البريد الإلكتروني | `mail`                                                                                    |
| اسم المستخدم      | `userPrincipalName`                                                                       |
| الهاتف            | `telephoneNumber`، ثم `businessPhones[0]`، ثم `mobilePhone`                               |
| نشط               | `accountEnabled`                                                                          |
| لغة الواجهة       | `preferredLanguage` (يُطابق لغة مثبتة في Chamilo، مع الرجوع إلى الإعداد الافتراضي للمنصة) |

يُكتب أيضًا ثلاثة حقول إضافية عند كل تسجيل دخول ناجح: `organisationemail` (= `mail`)، و`azure_id` (= `mailNickname`)، و`azure_uid` (= معرّف كائن Entra). تدعم هذه الحقول منطق مطابقة الحسابات أدناه.

## مطابقة عمليات تسجيل الدخول مع حسابات Chamilo الموجودة

عيّن `existing_user_verification_order` إلى قائمة مفصولة بفواصل من الأرقام `1`–`3` للتحكم في كيفية مطابقة تسجيل دخول Entra ID الوارد مع حساب Chamilo موجود:

| القيمة | يطابق مقابل                                          |
| ------ | ---------------------------------------------------- |
| `1`    | الحقل الإضافي `organisationemail` == `mail` في Entra |
| `2`    | الحقل الإضافي `azure_id` == `mailNickname` في Entra  |
| `3`    | الحقل الإضافي `azure_uid` == معرّف كائن Entra        |

تُجرَّب المواضع بالترتيب المدرج؛ وتفوز أول مطابقة نشطة (غير محذوفة حذفًا ناعمًا). القيمة غير الصالحة أو الفارغة تعود افتراضيًا إلى `1,2,3`. إذا لم تطابق أي من المواضع المكوّنة — وهذا هو الحال دائمًا في المرة الأولى التي يسجّل فيها مستخدم معيّن الدخول، لأن تلك الحقول الإضافية تُملأ *بعد* تسجيل دخول ناجح فقط — يعود Chamilo إلى مطابقة حقل `email` الخاص بـ Chamilo مع `mail` في Entra، ثم `username` مع `userPrincipalName`، بغض النظر عما كوّنته.

## تعيين الأدوار حسب المجموعات

اربط مجموعات أمان Entra ID بأدوار Chamilo باستخدام معرّفات الكائنات (GUID):

```yaml
authentication:
  1:
    oauth2:
      azure:
        group_id:
          admin: "<entra-group-object-id>"
          session_admin: "<entra-group-object-id>"
          teacher: "<entra-group-object-id>"
```

عند كل تسجيل دخول، يستدعي Chamilo Microsoft Graph `/v1.0/me/memberOf` باستخدام رمز الوصول الخاص بالمستخدم نفسه، ويقارن المجموعات المُرجَعة بهذه المعرّفات الثلاثة، بالترتيب **admin → session\_admin → teacher**. أول تطابق يفوز — فالمستخدم الموجود في مجموعتي المسؤول والمعلّم يُرقَّى إلى مسؤول فقط. أي شخص غير موجود في أي مجموعة مُعدَّة يحتفظ بدوره الحالي (أو بدور الطالب الافتراضي عند أول تسجيل دخول). يتطلب ذلك صلاحية التفويض `GroupMember.Read.All` المذكورة أعلاه.

## المصادقة بالشهادة

كبديل لـ `client_secret`، يمكنك المصادقة بشهادة بدلاً من ذلك:

```yaml
authentication:
  1:
    oauth2:
      azure:
        client_certificate_private_key: "<PEM private key, single line, with \\n for line breaks>"
        client_certificate_thumbprint: "<hex SHA1 thumbprint>"
```

ارفع الشهادة العامة المطابقة ضمن **Certificates & secrets** في تسجيل التطبيق، وانسخ بصمتها (تظهر بالنظام الست عشري في البوابة) إلى `client_certificate_thumbprint`. عند تعيين كلا المفتاحين، يبني Chamilo تأكيد عميل JWT موقَّع (RS256) بدلاً من إرسال `client_secret` — وينطبق ذلك على عمليات تسجيل الدخول التفاعلية وعلى مصادقة التطبيق فقط لأوامر المزامنة على حد سواء.

## مزامنة المستخدمين والمجموعات من Entra ID

أمران في وحدة التحكم يوفّران حسابات Chamilo ويحافظان عليها مباشرة من Entra ID، بمعزل عن تسجيل أي شخص دخولاً تفاعلياً. كلاهما يصادق بأسلوب التطبيق فقط (`client_credentials`)، لذا يحتاجان إلى صلاحيات Graph الخاصة بـ **التطبيق** المذكورة أعلاه، وكلاهما مُعدّ للجدولة في cron وليس للتشغيل يدوياً.

### `app:azure-sync-users`

يجلب المستخدمين من Microsoft Graph ويوفّر/يحدّث حسابات Chamilo المطابقة باستخدام نفس تعيين الحقول ومنطق مطابقة الحسابات كما في تسجيل الدخول التفاعلي.

* افتراضياً يجلب قائمة المستخدمين كاملة (`/v1.0/users`، مع الصفحات). عيّن `script_users_delta: true` لاستخدام `/v1.0/users/delta` بدلاً من ذلك — يحفظ Chamilo رابط الدلتا بين التشغيلات، لذا تجلب التشغيلات اللاحقة ما تغيّر فقط.
* عيّن `deactivate_nonexisting_users: true` لتعطيل حسابات Chamilo (ذات مصدر المصادقة Azure) التي لم تعد تظهر في جلب Entra ID. يعمل هذا في وضع الجلب الكامل فقط — وضع الدلتا لا يُرجع قائمة المستخدمين كاملة أبداً، لذا يُتجاهل هذا الإعداد عند تفعيل `script_users_delta`.
* يُعاد تطبيق تعيين أدوار المجموعات (أعلاه) لكل مستخدم مُزامَن خلال هذا التشغيل، وليس عند تسجيل الدخول فقط.

### `app:azure-sync-usergroups`

يجلب مجموعات Entra ID ويعكسها كصفوف في Chamilo (`Usergroup`).

* يجلب قائمة المجموعات كاملة (`/v1.0/groups`) أو، مع `script_usergroups_delta: true`، نقطة نهاية الدلتا، مع رابط دلتا خاص به يُتتبَّع بشكل منفصل.
* يقيّد `group_filter_regex` المجموعات التي تُزامَن، بالمطابقة مع الاسم المعروض للمجموعة.
* **كل تشغيل يمسح أولاً جميع الأعضاء الحاليين للصف المطابق في Chamilo**، ثم يعيد اشتراك الأعضاء الذين يُرجعهم Graph حالياً. يُطابَق الأعضاء مع مستخدمي Chamilo *الحاليين* فقط، باستخدام نفس [منطق مطابقة الحسابات](#matching-logins-to-existing-chamilo-accounts) كما في تسجيل الدخول — لا ينشئ هذا الأمر حسابات مستخدمين جديدة أبداً، وأي عضو مجموعة يتعذّر مطابقته مع حساب Chamilo موجود يُتخطّى بصمت.

## القيود المعروفة

* **لا يوجد تسجيل خروج موحّد.** تسجيل الخروج من Chamilo لا يسجّل خروج المستخدم من Entra ID أو من التطبيقات المتصلة الأخرى. يوجد مفتاح إعداد `force_logout` في `authentication.yaml` لكنه غير مُنفَّذ حالياً — اعتبره محجوزاً وليس فعّالاً.
* **إعادة تعيين كلمة المرور بلا معنى لحسابات Azure.** بما أن المصادقة تتم بالكامل عبر Entra ID، لا يحتفظ Chamilo بكلمة مرور محلية قابلة للاستخدام لهذه الحسابات.

## استكشاف الأخطاء وإصلاحها

* تظهر إخفاقات تسجيل الدخول (سمات مطلوبة ناقصة، أخطاء Graph API) للمستخدم كرسالة فلاش في صفحة تسجيل الدخول.
* تسجّل أوامر المزامنة المشكلات لكل سجل بتحذيرات وتواصل معالجة بقية الدفعة بدلاً من الإيقاف عند أول خطأ — راجع مخرجات الأمر في وحدة التحكم (أو حيث يلتقطها cron) بعد كل تشغيل.
* أبقِ نموذج تسجيل الدخول القياسي في Chamilo مفعّلاً حتى يتوفر للمسؤولين دائماً طريق للدخول إذا تعطّل تكامل Entra ID.
