Menu Permissions
نبدأ بتقديم مثال على Spring Boot يتضمن نظام قائمة. هذا المثال يستخدم jCasbin لإدارة صلاحيات القائمة. في النهاية، يهدف إلى تجريد وسيط برمجي، خصيصًا لصلاحيات القائمة، والذي يمكن توسيعه للغات أخرى يدعمها Casbin، مثل Go و Python.
1. ملفات التكوين
تحتاج إلى إعداد إدارة الأدوار والصلاحيات في ملف policy.csv
، بالإضافة إلى العلاقات الأبوية-الفرعية بين عناصر القائمة. لمزيد من التفاصيل، يرجى الرجوع إلى هذا المستودع على GitHub.
1.1 نظرة عامة
باستخدام policy.csv
، يمكنك تكوين صلاحيات الأدوار وهياكل القائمة بشكل مرن للتحكم الدقيق في الوصول. يحدد ملف التكوين هذا صلاحيات الوصول للأدوار المختلفة على عناصر القائمة المتنوعة، والعلاقات بين المستخدمين والأدوار، والعلاقات الهرمية بين عناصر القائمة.
1.2 تعريفات الصلاحيات (السياسات)
- قواعد السياسة: تُعرف السياسات ببادئة
p
، محددة الأدوار (sub
) وصلاحياتها (act
) على عناصر القائمة (obj
)، بالإضافة إلى تأثير القاعدة (eft
)، حيث يشيرallow
إلى أن الصلاحية ممنوحة، وdeny
يشير إلى أنها مرفوضة.
أمثلة:
p, ROLE_ROOT, SystemMenu, read, allow
تعني أن الدورROLE_ROOT
لديه صلاحية القراءة لعنصر القائمةSystemMenu
.p, ROLE_ROOT, UserMenu, read, deny
تعني أن الدورROLE_ROOT
مرفوض منه صلاحية القراءة لعنصر القائمةUserMenu
.
1.3 الأدوار وعلاقات المستخدمين
- وراثة الدور: تُعرف علاقات المستخدم-الدور والتسلسل الهرمي للأدوار ببادئة
g
. هذا يسمح للمستخدمين بوراثة الصلاحيات من دور واحد أو أكثر.
أمثلة:
g, user, ROLE_USER
تعني أن المستخدمuser
مُعين للدورROLE_USER
.g, ROLE_ADMIN, ROLE_USER
تعني أنROLE_ADMIN
يرث الصلاحيات منROLE_USER
.
1.4 هرمية عناصر القائمة
- علاقات القائمة: تُعرف العلاقات الأبوية-الفرعية بين عناصر القائمة ببادئة
g2
، مما يساعد في بناء هيكل القائمة.
أمثلة:
g2, UserSubMenu_allow, UserMenu
تشير إلى أنUserSubMenu_allow
هو قائمة فرعية لـUserMenu
.g2, (NULL), SystemMenu
تشير إلى أنSystemMenu
ليس لديها عنصر قائمة فرعي، أي أنها عنصر قائمة رئيسي.
1.5 وراثة صلاحيات القائمة والقواعد الافتراضية
عند إدارة صلاحيات القائمة مع jCasbin، تتبع العلاقة بين القوائم الأبوية والفرعية قواعد وراثة محددة، مع قاعدتين افتراضيتين مهمتين:
وراثة صلاحيات القائمة الأبوية:
إذا تم منح القائمة الأبوية صلاحية allow
بشكل صريح، فإن جميع القوائم الفرعية تفترض افتراضيًا صلاحية allow
ما لم يتم تحديدها بشكل صريح كـ deny
. هذا يعني أنه بمجرد أن تكون القائمة الأبوية قابلة للوصول، فإن القوائم الفرعية تكون قابلة للوصول افتراضيًا.
التعامل مع القوائم الأبوية بدون إعدادات صلاحية مباشرة:
إذا لم تكن القائمة الأبوية لديها إعدادات صلاحية مباشرة (لا يُسمح بها صراحةً ولا يُرفض بها صراحةً) ولكن لديها قائمة فرعية واحدة على الأقل منحت صلاحية allow
بشكل صريح، فإن القائمة الأبوية تُعتبر ضمنيًا لديها صلاحية allow
. هذا يضمن أن المستخدمين يمكنهم التنقل إلى هذه القوائم الفرعية.
1.6 قواعد وراثة الصلاحيات الخاصة
فيما يتعلق بوراثة الصلاحيات بين الأدوار، وخاصة في السيناريوهات التي تتضمن صلاحيات deny
، يجب اتباع القواعد التالية لضمان أمان النظام والتحكم الدقيق في الصلاحيات:
التمييز بين الرفض الصريح والافتراضي:
إذا تم رفض دور ما، مثل ROLE_ADMIN
، بشكل صريح من الوصول إلى عنصر قائمة، مثل AdminSubMenu_deny
(مُعلم كـ deny
)، فإنه حتى إذا تم وراثة هذا الدور من قبل دور آخر (مثل ROLE_ROOT
)، فإن الدور الوريث لا يُسمح له بالوصول إلى عنصر القائمة المرفوض. هذا يضمن ألا تتم تجاوز السياسات الأمنية الصريحة بسبب وراثة الدور.
وراثة صلاحيات الرفض الافتراضية:
على العكس من ذلك، إذا كان رفض دور للوصول إلى عنصر قائمة (مثل UserSubMenu_deny
) هو افتراضي (لم يُعلم صراحةً كـ deny
، ولكن لأنه لم يُمنح صراحةً صلاحية allow
)، فعندما يُورث هذا الدور من قبل دور آخر (مثل ROLE_ADMIN
)، يمكن للدور الوريث تجاوز حالة الرفض الافتراضية، مما يسمح بالوصول إلى هذه العناصر في القائمة.
1.7 وصف المثال
policy:
p, ROLE_ROOT, SystemMenu, read, allow
p, ROLE_ROOT, AdminMenu, read, allow
p, ROLE_ROOT, UserMenu, read, deny
p, ROLE_ADMIN, UserMenu, read, allow
p, ROLE_ADMIN, AdminMenu, read, allow
p, ROLE_ADMIN, AdminSubMenu_deny, read, deny
p, ROLE_USER, UserSubMenu_allow, read, allow
g, user, ROLE_USER
g, admin, ROLE_ADMIN
g, root, ROLE_ROOT
g, ROLE_ADMIN, ROLE_USER
g2, UserSubMenu_allow, UserMenu
g2, UserSubMenu_deny, UserMenu
g2, UserSubSubMenu, UserSubMenu_allow
g2, AdminSubMenu_allow, AdminMenu
g2, AdminSubMenu_deny, AdminMenu
g2, (NULL), SystemMenu
MenuName | ROLE_ROOT | ROLE_ADMIN | ROLE_USER |
---|---|---|---|
SystemMenu | ✅ | ❌ | ❌ |
UserMenu | ❌ | ✅ | ❌ |
UserSubMenu_allow | ❌ | ✅ | ✅ |
UserSubSubMenu | ❌ | ✅ | ✅ |
UserSubMenu_deny | ❌ | ✅ | ❌ |
AdminMenu | ✅ | ✅ | ❌ |
AdminSubMenu_allow | ✅ | ✅ | ❌ |
AdminSubMenu_deny | ✅ | ❌ | ❌ |
2. تحكم بأذونات القائمة
يمكن تحديد قائمة جميع عناصر القائمة التي يمكن الوصول إليها بواسطة اسم مستخدم معين من خلال الدالة findAccessibleMenus()
المتاحة في MenuService. للتحقق مما إذا كان لدى مستخدم معين الحقوق للوصول إلى عنصر قائمة محدد، يمكن استخدام طريقة checkMenuAccess()
. هذا النهج يضمن أن أذونات القائمة يتم التحكم بها بفعالية، مستفيدة من قدرات jCasbin لإدارة حقوق الوصول بكفاءة.