برای اینکه هر بار برای تغییر قوانین دسترسی، مجبور نباشم کد رو عوض بکنم و نسخه جدید منتشر بکنم، لازم بود بتونم قوانین دسترسی رو در قالب تنظیمات (config) ذخیره کنم. حالا با داشتن کدی که بتونه این تنظیمات رو بخونه و محدودیتهای لازم رو اعمال بکنه، میتونم به سادگی و بدون تغییر کد، محدودیتهای دسترسی رو عوض بکنم. امّا برای بیان دسترسیها در قالب config، نیاز به زبانی دارم که بشه حالتهای مختلف رو توصیف کرد. با توجه به اینکه نیازمندیمون کنترل دسترسی مبتنی بر ویژگی (Attribute-based Access Control) بود، جستجویی کردم و رسیدم به PERM metamodel و Casbin. تو این نوشته توضیح میدم که چطور با این دو ابزار یه سیستم کنترل دسترسی منعطف میشه درست کرد.
کنترل دسترسی مبتنی بر نقش (Role-based Access Control) و مبتنی بر ویژگی (به اختصار ABAC)، دو نوع متداول از کنترل دسترسی هستن. تو مدل RBAC، اجازهی انجام یه کار، فقط وابسته به نقش درخواستکننده است. برای نمونه دسترسیها به این شکل بیان میشه:
اگر مدیر (admin) بود، مجازه همه کاری بکنه.
اگر ناظم (moderator) بود، مجاز نیست پروژه رو حذف بکنه.
اگر مهمان (guest) بود، مجاز نیست چیزی رو ویرایش بکنه.
امّا مدل ABAC به ما این امکان رو میده که براساس ویژگیهای کاربر (Subject)، مؤلفههای درخواستی که داره (Action)، خصیصههای چیزی که قراره بهش دسترسی پیدا کنه (Object یا Resource) و شرایط (Context یا Environment)، تصمیم بگیریم که مجوز دسترسی بدیم یا نه. برای نمونه، یه دسترسیها به این شکل بیان میشه:
اگر کارمند بود، تا حالا وام نگرفته بود، و مبلغ قسطش کمتر از ۱/۴ حقوقش بود، اجازه داره وام بگیره.
اگر اسمش ب.ز بود، از وثیقهاش نپرسید و وامش دهید!
مدل ABAC، بر خلاف مدل RBAC که فقط متکی به نقشها و دسترسیهای از پیش تعریف شده است، میتونیم قوانین دسترسی رو به صورت جملات منطقی پویا و آگاه به زمانه (یاد فقه افتادم ?) تعریف کنیم.
معماری پیشنهادی برای کنترل دسترسی مبتنی بر ویژگی، از سه جزء اصلی تشکیل شده:
برای توصیف منطق کنترل دسترسی به نحو قابل فهم برای کامپیوتر، نیاز به یه زبان (metamodel) داریم. PERM metamodel یه زبان خیلی ساده برای توصیف قوانین دسترسیه که از چهار بخش اصلی تشکیل شده:
علاوهبر این چهار بخش اصلی، اگر بخوایم از مدل RBAC استفاده کنیم، لازمه که نقشها رو هم توصیف کنیم. البته از اونجایی که Role، در اصل تعریف «گروه کاربران»ــه، میتونیم از این امکان برای گروهبندی امکانات و تعریف سلسله تو مدل ABAC استفاده کنیم.
بعد از اینکه این مدلها و روابط رو توصیف کردیم، میتونیم شروع کنیم به نوشتن قوانین (که معادل ساختن instanceهایی از ساختار تعریف شده در Policyــه). حالا ما میتونیم درخواستهای دسترسی (که instanceهایی از Request هستن) رو بگیریم و بررسی کنیم.
با شناخت مدل PERM میتونیم معماری ABAC رو به این صورت بیان کنیم:
فرض کنین ما یه اپراتور هستیم (مثلاً ایرانسل!) و مشتریها میتونن بسته افزایش بخرن. منابع مختلفی هم داریم: اینترنت، تماس، پیامک و... . ما میخوایم کنترل کنیم که هر کسی متناسب با بستهای که داره و ظرفیت باقیمونده از اون بسته، به منابع دسترسی داشته باشه.
در ابتدا مدل رو اینطوری تعریف میکنیم:
حالا وقت تعریف کردن قوانینه:
دو تا بسته تعریف کردیم؛ یه بستهی برنزی که ۱۰۰تا پیامک به کاربر میده و یه بستهی طلایی که امکان ۱۰۰دقیقه مکالمه رو فراهم میکنه.
الآن دیگه میتونیم بریم کد بنویسیم:
تو خط ۷ ما یه Enforce با استفاده از مدل و قوانینی که قبلاً تعریف کرده بودیم، ایجاد کردیم. بعد تابع matchUsage رو که توی مدل استفاده کرده بودیم رو اینطور تعریف کردیم که مقدار مورد درخواست کاربر + استفاده فعلیش باید کمتر از محدودیت بسته باشه. آخر سر هم چند نمونه درخواست رو بررسی کردیم:
به همین سادگی. حالا فردا روز اگر قرار شد محدودیت بستهها تغییر کنه یا بسته جدیدی اضافه بشه یا ...، دیگه ما لازم نیست چیزی جز فایل rules.csv رو تغییر بدیم.
اگر یه نگاهی به استاندارد اصلی ABAC یعنی XACML بندازین، متوجه میشین که PERM نسبت به اون خیلی خیلی سادهتره. حتی توسعهدهندههاش دلیل معرفی نکردن چیز سادهای مثل data type رو هم همین گفتن. برای اینکه با Casbin و امکاناتی که میده بیشتر آشنا بشین و مثالهایی از سیستمهای کنترل دسترسی مختلف رو ببینین، میتونین یه سر به سایتش بزنین.