انتقل إلى المحتوى

المصادقة وRBAC

ما هو

تصادق ManpowerIQ المستخدمين بـ اسم مستخدم/كلمة مرور، وتُصدِر رمز وصول JWT، وتُخوِّل كل إجراء محمي عبر نموذج RBAC متمحور حول الصلاحيات — كتالوج عام لرموز الصلاحيات، وأدوار محصورة بوحدة العمل تحزمها، وسمات [Authorize("x.y")] مُحوَّلة إلى فحوص صلاحية حيّة.

لماذا بُني بهذه الطريقة

التخويل على الصلاحيات، لا على أسماء الأدوار. تختلف أدوار الميناء بين شركات التشغيل، لكن القدرات الكامنة (employee.view، roster.create…) ثابتة. فحص الصلاحيات بدلًا من الأدوار المُرمَّزة يتيح لكل وحدة عمل تشكيل أدوارها الخاصة بينما تبقى القدرات نفسها مُنفَّذة باتّساق (الورقة 01 §how-it-works). كتالوج الصلاحيات عام؛ الأدوار محصورة بالمستأجر (الورقة 01 §decisions).

أُبقي نطاق المصادقة متعمَّد الحدّ الأدنى للإصدار v1: رمز وصول واحد قصير العمر، دون تدوير رمز تحديث ودون مزوّد هوية خارجي. تلك مُصمَّمة-للاحق، لا مبنية (انظر حالة البناء).

كيف يعمل

تسجيل الدخول والرمز

sequenceDiagram
    participant U as User (web)
    participant A as AuthService
    participant J as JwtTokenMinter
    U->>A: username + password
    A->>A: verify hash, check lockout
    A->>J: MintForUserAsync(user, expiresInHours: 8)
    J-->>A: signed JWT (claims + 8h expiry)
    A-->>U: access token
    U->>U: store token, send as Bearer on every request
  • يتحقّق AuthService من hash كلمة المرور، ويُنفِّذ الإغلاق، ثم يستدعي JwtTokenMinter.MintForUserAsync(user, expiresInHours: 8) (AuthService.cs:111). ينتهي الرمز 8 ساعات بعد الإصدار (JwtTokenMinter.cs:80، expires: DateTime.UtcNow.AddHours(8)).
  • يحمل JWT المطالبات التي تقود كلًّا من تعدّد المستأجرين والتخويل: business_unit_id، is_super_admin، sub، username، permission، scoped_permissions (الورقة 01 §how-it-works).
  • حماية الحساب — تتضمّن بيانات اعتماد المستخدم password_hash، password_change_required، failed_login_count، وlockout_until (الورقة 01 §entities، User.cs؛ أُضيفت بيانات الاعتماد في MIQ018a).
  • بديل التطوير — في Development دون رمز، يُحلّ النظام إلى BU=1 / "dev" (الورقة 01 MUST-NOT #6). ليس مسار إنتاج.

إنفاذ الصلاحيات

flowchart LR
    REQ["[Authorize(\"employee.view\")]"] --> PPP[PermissionPolicyProvider<br/>name contains a dot → PermissionRequirement]
    PPP --> PAH[PermissionAuthorizationHandler]
    PAH --> CTP[CurrentTenantProvider.HasPermission]
    CTP --> R{super-admin OR<br/>code in permissions OR<br/>code in scoped_permissions}
    R -->|yes| ALLOW[allow]
    R -->|no| DENY[403]
  • الإنشاء التلقائي للسياسة — يبني PermissionPolicyProvider سياسة على الفور لأي اسم سياسة [Authorize("…")] يحوي نقطة؛ وكل ما عداه يمرّ إلى المزوّد الافتراضي (الورقة 01 §rules، PermissionPolicyProvider.cs:25-36).
  • الفحص — يستدعي PermissionAuthorizationHandler الدالة ICurrentTenantProvider.HasPermission، وهي super-admin OR exact code in permission claims OR in scoped_permissions. تطابق HasPermissionForDepartment إضافةً dept_id للمنح المحصورة بالقسم (الورقة 01 §rules، CurrentTenantProvider.cs:99-113).

النموذج

  • Permission — بيانات مرجعية عامة (بلا business_unit_idcode منقّط (مثلًا employee.view)، مُجمَّع حسب category (الورقة 01 §entities، Permission.cs).
  • Role — محصور بالمستأجر (TenantEntity)، حزمة مُسمّاة، فريد (business_unit_id, code) (الورقة 01 §entities، Role.cs).
  • UserRole — منح دور لمستخدم، اختياريًا scope_department_id، بتواريخ effective_from / effective_to (الورقة 01 §entities، UserRole.cs).

الكتالوج المُتحقَّق منه هو 97 صلاحية عبر 9 أدوار (كان خط أساس MIQ-003 هو 40 صلاحية / 7 أدوار؛ أُضيف HR_DIRECTOR وCOO لاحقًا). المصفوفة القانونية الكاملة هي صفحة مرجع مصفوفة RBAC، مزروعة من Sprint/RBAC_RolePermission_Extract.md.

مزالق / قيود

  • لا رموز تحديث. يسكّ تسجيل الدخول رمز وصول واحد لمدة 8 ساعات؛ لا نقطة نهاية تحديث/تدوير (مُتحقَّق منه: grep عن refresh_token/RefreshToken → لا تطابقات). عند انتهاء الرمز يعيد المستخدم المصادقة.
  • لا SSO / Active Directory. المصادقة محلية باسم مستخدم/كلمة مرور فقط (مُتحقَّق منه: grep عن AzureAd/OpenIdConnect/SAML → لا تطابقات). كان SSO "مُخطّطًا للجولة 1" في التسليم لكنه غير مبني.
  • Permission جدول عام بلا مرشّح وحدة عمل — فقط Role/RolePermission/UserRole/User محصورة بالمستأجر (الورقة 01 MUST-NOT #4).
  • يجب أن تحوي أسماء السياسات نقطة لتُعامَل كمتطلّب صلاحية؛ اسم بلا نقطة يمرّ إلى المزوّد الافتراضي (مثلًا "Authenticated").
  • يتجاوز super-admin حصر وحدة العمل بالتصميم — منح قوي، مقيَّد عمدًا بالاستخدام الموثوق (الورقة 01 §rules).

حالة البناء

  • Available — تسجيل دخول JWT باسم مستخدم/كلمة مرور، وإغلاق الحساب، وكتالوج الصلاحيات، والأدوار المحصورة بوحدة العمل، والمنح المحصورة بالقسم وذات التواريخ الفعّالة، وفحص الصلاحية في وقت التشغيل — كلها تُسلَّم وتُنفَّذ (الورقة 01 §build-status).
  • Planned — رموز تحديث JWT؛ SSO / Active Directory. مُوثَّقة على أنها غائبة، لا قيد الاستخدام.

ذات صلة