طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 241 · تحليل وتصميم برمجيات الويب
الدرس 16 · الوحدة 7: تصميم صلاحيات المستخدمين وتنظيمها بشكل فعّال

نماذج التحكم بالوصول ومصفوفة الصلاحيات

كيف تنظّم الصلاحيات في نموذج واضح يدير الوصول للميزات والبيانات حسب دور المستخدم؟ ⏱ نحو 45 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تقارن نماذج ACL و RBAC و ABAC وتختار المناسب.
  • تسمّي الصلاحيات بصيغة المورد:الفعل.
  • تبني مصفوفة صلاحيات للأدوار والموارد مع شروط الملكية.
  • تصمم نموذج بيانات RBAC بجداول الربط.

١ثلاثة نماذج للتحكم بالوصول

بعد تحليل الأدوار نحتاج نموذج صلاحيات Authorization Model: طريقة منظمة تقرر بها «هل يحق لهذا المستخدم هذا الفعل على هذا المورد؟». ثلاثة نماذج شائعة:

النموذجالفكرةمثاليناسب
ACL قائمة التحكملكل مورد قائمة بالمستخدمين المسموح لهمملف مشترك مع أشخاص بأسمائهممشاركة ملفات بين أفراد
RBAC حسب الدورالصلاحيات تُعطى للأدوار، والمستخدمون يُسندون إلى أدواردور «موظفة تسجيل» يملك «اعتماد الطلبات»أغلب أنظمة المؤسسات
ABAC حسب الخصائصالقرار بقاعدة على خصائص المستخدم والمورد والسياق«المدرب يرى التسجيل إن كانت الدورة دورته»قواعد دقيقة لا تكفيها الأدوار

النموذج العملي لمعظم تطبيقات الويب: RBAC أساسًا، مع شروط ملكية قليلة (من ABAC) حيث يلزم. نصمم بهذه الطريقة في «دورات».

٢تسمية الصلاحيات

الصلاحية = فعل على مورد. تسميتها باتفاق ثابت المورد:الفعل تجعلها واضحة وقابلة للبحث والتدقيق:

الصلاحيةمعناها
course:readعرض الدورات
course:createإضافة دورة
enrollment:createإنشاء طلب تسجيل
enrollment:read:ownعرض طلبات التسجيل الخاصة بالمستخدم فقط
enrollment:approveاعتماد طلب أو رفضه
report:financeعرض التقارير المالية
user:manageإدارة الحسابات وإسناد الأدوار

٣مصفوفة الصلاحيات

مصفوفة الصلاحيات جدول واحد يلخص التصميم كله: الأدوار أعمدة، والصلاحيات صفوف. يقرؤها العميل ويعتمدها، ويبرمج منها المطور، ويختبر منها المختبِر:

الصلاحيةزائرمتدربمدربتسجيلمدير
course:read✓✓✓✓✓
enrollment:create✗✓✗✗✗
enrollment:read✗الخاصة بهدوراته✓✓
enrollment:approve✗✗✗✓✗
attendance:record✗✗دوراته✗✗
report:finance✗✗✗✗✓
user:manage✗✗✗✗✓

٤نموذج بيانات RBAC

لكي يحفظ النظام الأدوار والصلاحيات ويعدّلها المدير دون تغيير الكود، نصمم لها بيانات. المستخدم له دور أو أكثر، والدور يمنح صلاحية أو أكثر:

diagram.mmd
classDiagram  class User["المستخدم"] {    +int id    +String email    +can(String permission) bool  }  class Role["الدور"] {    +int id    +String name  }  class Permission["الصلاحية"] {    +int id    +String code  }  User "0..*" --> "1..*" Role : له  Role "0..*" --> "1..*" Permission : يمنح

له

يمنح

0..*

0..*

1..*

1..*

المستخدم

+int id

+String email

+can(String permission) : bool

الدور

+int id

+String name

الصلاحية

+int id

+String code

العلاقتان كثير إلى كثير: مستخدم بعدة أدوار، ودور لعدة مستخدمين. والعملية can(permission) هي ما يستدعيه الكود: «هل يملك هذا المستخدم الصلاحية عبر أي من أدواره؟».

وفي قاعدة البيانات تصبح كل علاقة كثير إلى كثير جدول ربط، كما تعلمنا في الدرس 9. هذا تحدي الدرس.

توقّع وتحقّق

في RBAC تُعطى الصلاحيات لـ:

«المدرب يرى التسجيل إن كانت الدورة دورته» قاعدة من نوع:

صيغة تسمية الصلاحيات المقترحة:

كيف تُحفظ علاقة الأدوار بالصلاحيات في قاعدة البيانات؟

الخلاصة

تحدٍّ تصميمي: جداول RBAC

متقدم

صمّم مخطط الكيانات الذي يحفظ المستخدمين وأدوارهم وصلاحيات كل دور، بحيث يستطيع المدير تعديلها دون تغيير الكود.

المطلوب:
  • ثلاثة جداول أساسية: USERS و ROLES و PERMISSIONS، لكل منها PK.
  • جدولا ربط: USER_ROLES (user_id و role_id) و ROLE_PERMISSIONS (role_id و permission_id) بمفاتيح أجنبية.
  • كل جدول أساسي في علاقة «واحد إلى كثير» مع جدول الربط الخاص به.
  • رمز الصلاحية code فريد UK.
✓ التحقق الآلي: يقرأ المختبر مخططك (العناصر والروابط) ويفحصه
  • المخطط مكتوب بصيغة صحيحة ويُرسم
  • نوعه: مخطط كيانات erDiagram
  • جدول PERMISSIONS
  • جدول USER_ROLES
  • جدول ROLE_PERMISSIONS
  • PERMISSIONS له PK
  • رمز الصلاحية فريد
  • USER_ROLES فيه user_id FK
  • USER_ROLES فيه role_id FK
  • ROLE_PERMISSIONS فيه permission_id FK
  • USERS واحد ← USER_ROLES كثير
  • ROLES واحد ← USER_ROLES كثير
  • ROLES واحد ← ROLE_PERMISSIONS كثير
  • PERMISSIONS واحد ← ROLE_PERMISSIONS كثير

💡 تلميح 1
كل علاقة كثير إلى كثير ← جدول ربط فيه مفتاحان أجنبيان.
💡 تلميح 2
العلاقة: USERS ||--o{ USER_ROLES : "له".
💡 تلميح 3
الفريد: string code UK.

حاول بنفسك أولًا؛ للتصميم أكثر من حلّ صحيح، والفحص يتأكد من العناصر الأساسية فقط.

diagram.mmd
erDiagram  USERS ||--o{ USER_ROLES : "له"  ROLES ||--o{ USER_ROLES : "مسند إلى"  ROLES ||--o{ ROLE_PERMISSIONS : "يمنح"  PERMISSIONS ||--o{ ROLE_PERMISSIONS : "ضمن"  USERS {    int id PK    string email UK  }  ROLES {    int id PK    string name UK  }  PERMISSIONS {    int id PK    string code UK  }  USER_ROLES {    int user_id FK    int role_id FK  }  ROLE_PERMISSIONS {    int role_id FK    int permission_id FK  }

له

مسند إلى

يمنح

ضمن

USERS

int

id

PK

string

email

UK

USER_ROLES

int

user_id

FK

int

role_id

FK

ROLES

int

id

PK

string

name

UK

ROLE_PERMISSIONS

int

role_id

FK

int

permission_id

FK

PERMISSIONS

int

id

PK

string

code

UK

انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس