کنترل دسترسی با Casbin و PERM metamodel

برای اینکه هر بار برای تغییر قوانین دسترسی، مجبور نباشم کد رو عوض بکنم و نسخه جدید منتشر بکنم، لازم بود بتونم قوانین دسترسی رو در قالب تنظیمات (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 که فقط متکی به نقش‌ها و دسترسی‌های از پیش تعریف شده است، می‌تونیم قوانین دسترسی رو به صورت جملات منطقی پویا و آگاه به زمانه (یاد فقه افتادم ?) تعریف کنیم.مدل ABAC چطور پیاده‌سازی می‌شه؟معماری پیشنهادی برای کنترل دسترسی مبتنی بر ویژگی، از سه جزء اصلی تشکیل شده:اجرای احکام یا Policy Enforcement Point: مسئول حفاظته و بلده چطور درخواست کاربر رو تبدیل به عریضه (Request) بکنه. بعد از وارسی درخواست کاربر، با دادگاه برای کسب مجوز مکاتبه می‌کنه و اگر مجوز داده نشد، درخواست کاربر رو رد می‌کنه.دادگاه یا Policy Decision Point: اینجا عریضه تحویل می‌گیره و بر اساس قانون (Policy) جواب می‌ده که آیا دسترسی مجازه یا نه (Permit یا Deny). اگر برای بررسی درخواست نیاز به اطلاعات بیشتری داشته باشه، از آگاهی (PIP) استعلام می‌کنه. آگاهی یا Policy Information Point: رابط PDP با سیستم‌های اطلاعاتی بیرونیه.مدل PERM چیه؟برای توصیف منطق کنترل دسترسی به نحو قابل فهم برای کامپیوتر، نیاز به یه زبان (metamodel) داریم. PERM metamodel یه زبان خیلی ساده برای توصیف قوانین دسترسیه که از چهار بخش اصلی تشکیل شده:قانون (Policy): این مدل، ساختار قواعد دسترسی رو بیان می‌کنه. برای نمونه، یه قانون می‌تونه با ساختار «کی (Subject) مجاز به چه کار (Action) با چی (Object) است» بیان بشه.دقت کنین که اینجا فقط داریم ساختار قوانین رو توصیف می‌کنیم (مثل Class در طراحی شیءگرا)، نه خود قوانین رو (مثل Object در طراحی شیء‌گرا).عریضه (Request): این مدل، ساختار درخواست دسترسی رو در بیان می‌کنه. در حالت خیلی ساده، یه عریضه می‌تونه با ساختار «کی (Subject) اجازه‌ی چه کار (Action) با چی (Object) می‌خواد؟».رابط (Matcher): رابطه‌ یا تابعی که مشخص می‌کنه چطور یه درخواست به یه قانون مرتبط میشه. حاصل انطباق یه درخواست و قانون، حکم اون قانونه (مجاز یا غیرمجاز). در حالت ساده، با برابر بودن «کی»، «چه کار» و «چی» بین درخواست و قانون، متوجه می‌شیم این قانون مناسبی برای بررسی این درخواسته.تأثیر (Effect): این رابطه مشخص می‌کنه که چطور حکم چند تا قانون با هم ترکیب می‌شن. برای نمونه، می‌تونیم بگیم «اگر حداقل یه مجوز داشتیم» (مثل OR منطقی).علاوه‌بر این چهار بخش اصلی، اگر بخوایم از مدل RBAC استفاده کنیم، لازمه که نقش‌ها رو هم توصیف کنیم. البته از اونجایی که Role، در اصل تعریف «گروه کاربران»ــه، می‌تونیم از این امکان برای گروه‌بندی امکانات و تعریف سلسله تو مدل ABAC استفاده کنیم.بعد از اینکه این مدل‌ها و روابط رو توصیف کردیم، می‌تونیم شروع کنیم به نوشتن قوانین (که معادل ساختن instanceهایی از ساختار تعریف شده در Policyــه). حالا ما می‌تونیم درخواست‌های دسترسی (که instanceهایی از Request هستن) رو بگیریم و بررسی کنیم.نحوه بررسی درخواست دسترسی در مدل PERMبا شناخت مدل PERM می‌تونیم معماری ABAC رو به این صورت بیان کنیم:اجرای احکام (PEP) درخواست کاربر رو تبدیل به یه نمونه از Request میکنهدادگاه (PDP) با منطق توصیف شده توسط PERM، درخواست‌ها رو بررسی می‌کنه. بررسی یه نمونهفرض کنین ما یه اپراتور هستیم (مثلاً ایرانسل!) و مشتری‌ها می‌تونن بسته افزایش بخرن. منابع مختلفی هم داریم: اینترنت، تماس، پیامک و... . ما می‌خوایم کنترل کنیم که هر کسی متناسب با بسته‌ای که داره و ظرفیت باقی‌مونده از اون بسته، به منابع دسترسی داشته باشه.در ابتدا مدل رو اینطوری تعریف می‌کنیم:model.confساختار درخواست که با r مشخص شده، به ما میگه که هر درخواست دسترسی ۴تا مؤلفه داره: بسته‌ی کاربر، چیزی که می‌خواد (پیامک، تماس، ...)، مقداری که درخواست کرده و میزان مصرفش تا الآن.ساختار قوانین که با p مشخص شدن، نشون میدن که قوانین ۳تا مؤلفه دارن:‌ چه بسته‌ای، مربوط به چه چیزی و تا چه میزان مصرف.رابطه‌ی e مشخص می‌کنه که اگر فقط یکی از قوانین جور شد، مجوز صادر میشهرابطه‌ی m مشخص می‌کنه که برای اینکه یه قانون رو برای یه درخواست به کار ببریم، باید اولاً بسته و نوع resource با درخواست یکی باشه، و در ثانی مقدار مورد تقاضای کاربر با محدودیت بسته بخونه. با توجه به اینکه تو مدل PERM و Casbin، نوع داده رو نمی‌تونیم مشخص کنیم و همه چی string فرض میشه. امّا خوشبختانه امکان تعریف توابع رو بهمون میده و ما اینجا برای مقایسه نیاز کاربر و محدودیت بسته، یه تابع خودمون تعریف کردیم (که توی کد خواهیم دید).حالا وقت تعریف کردن قوانینه:rules.csvدو تا بسته تعریف کردیم؛ یه بسته‌ی برنزی که ۱۰۰تا پیامک به کاربر میده و یه بسته‌ی طلایی که امکان ۱۰۰دقیقه مکالمه رو فراهم می‌کنه.الآن دیگه می‌تونیم بریم کد بنویسیم:تو خط ۷ ما یه Enforce با استفاده از مدل و قوانینی که قبلاً تعریف کرده بودیم، ایجاد کردیم. بعد تابع matchUsage رو که توی مدل استفاده کرده بودیم رو اینطور تعریف کردیم که مقدار مورد درخواست کاربر + استفاده فعلی‌ش باید کمتر از محدودیت بسته باشه. آخر سر هم چند نمونه درخواست رو بررسی کردیم:اجازه داره با بسته برنزی، ۲۰ تا پیامک بفرسته وقتی که تا الآن ۷۰تا پیامک فرستاده؟‌ بله!اجازه داره با بسته برنزی، ۲۰ تا پیامک بفرسته وقتی که تا الآن ۹۰ تا پیامک فرستاده؟ نه!اجازه داره با بسته طلایی، ۹۹دقیقه مکالمه داشته باشه وقتی هنوز هیچ مصرفی نداشته؟ بله!به همین سادگی. حالا فردا روز اگر قرار شد محدودیت بسته‌ها تغییر کنه یا بسته جدیدی اضافه بشه یا ...، دیگه ما لازم نیست چیزی جز فایل rules.csv رو تغییر بدیم.اگر یه نگاهی به استاندارد اصلی ABAC یعنی XACML بندازین، متوجه می‌شین که PERM نسبت به اون خیلی خیلی ساده‌تره. حتی توسعه‌دهنده‌هاش دلیل معرفی نکردن چیز ساده‌ای مثل data type رو هم همین گفتن. برای اینکه با Casbin و امکاناتی که میده بیشتر آشنا بشین و مثال‌هایی از سیستم‌های کنترل دسترسی مختلف رو ببینین، می‌تونین یه سر به سایتش بزنین.