فیلتر کنترل دسترسی
ACF (مخفف Access Control Filter) یک روش ساده اعتبارسنجی است که بصورت یک فیلتر در yiifiltersAccessControl پیادهسازی شده است و بهترین کاربرد را در برنامههایی دارد که فقط نیاز به برخی کنترلهای ساده دسترسی دارند. همانطور که از نامش پیداست، ACF یک فیلتر عملیات است که میتواند در یک کنترلر یا ماژول بکار گرفته شود. وقتی که یک کاربر درخواست اجرای یک اکشن را دارد، ACF فهرستی از [url=#$rules-detail]قوانین دسترسی[/url] را بررسی میکند تا مشخص نماید که کاربر مجاز به دسترسی به اکشن درخواستی است یا نه.
کد زیر نحوه استفاده از ACF را در کنترلر site نشان میدهد:
use yiiwebController;
use yiifiltersAccessControl;
class SiteController extends Controller
{
public function behaviors()
{
retu [
'access' => [
'class' => AccessControl::className(),
'only' => ['login', 'logout', 'signup'],
'rules' => [
[
'allow' => true,
'actions' => ['login', 'signup'],
'roles' => ['?'],
],
[
'allow' => true,
'actions' => ['logout'],
'roles' => ['@'],
],
],
],
];
}
// ...
}
[
'class' => AccessControl::className(),
...
'denyCallback' => function ($rule, $action) {
throw new Exception('You are not allowed to access this page');
}
]
use yiifiltersAccessControl;
class SiteController extends Controller
{
public function behaviors()
{
retu [
'access' => [
'class' => AccessControl::className(),
'only' => ['special-callback'],
'rules' => [
[
'actions' => ['special-callback'],
'allow' => true,
'matchCallback' => function ($rule, $action) {
retu date('d-m') === '31-10';
}
],
],
],
];
}
// Match callback called! This page can be accessed only each October 31st
public function actionSpecialCallback()
{
retu $this->render('happy-halloween');
}
}
Roll Based Access Control یا به اختصار RBAC یک روش ساده و در عین حال قدرتمند برای کنترل مرکزی دسترسی ارائه میدهد. لطفاً به ویکیپدیا برای جزئیات مقایسه RBAC با سایر الگوهای سنتی کنترل دسترسی مراجعه کنید.
Yii یک سیستم عمومی سلسله مراتبی از RBAC را با پیروی از مدل RBAC معرفی شده توسط NIST پیادهسازی کرده است. این مدل، قابلیت RBAC را ازطریق کامپوننت authManager ارائه میکند.
استفاده از RBAC شامل دو مرحله است. بخش اول پیادهسازی دادههای اعتبارسنجی RBAC است و بخش دوم شامل استفاده از آن دادهها برای چککردن سطح دسترسی در مکان موردنیاز است. برای اینکه توضیحات بعدی را راحتتر درک کنید، ابتدا برخی از مفاهیم پایه RBAC را توضیح میدهیم:
مفاهیم پایه
یک نقش، نمایانگر مجموعهای از مجوزها است (برای مثال، ایجاد پست، اصلاح پست). یک نقش ممکن است به یک یا چند کاربر دادهشود. برای بررسی اینکه یک کاربر مجوز خاصی را دارد یا نه، میتوانیم چککنیم که آیا آن کاربر دارای نقشی هست که شامل آن مجوز باشد یا خیر؟
درکنار هر نقش یا مجوز ممکن است یک قانون (Rule) نیز ذکر شود. یک قانون معادل بخشی از کد است که باید در حین انجام عملیات بررسی دسترسی اجرا شود تا مشخصگردد که نقش یا مجوز موردنظر به کاربر جاری اختصاص داده میشود یا نه؟ برای مثال، مجوز «اصلاح پست» ممکن است دارای قانونی باشد که چک میکند آیا کاربر جاری، ایجاد کننده پست است یا خیر؟ درطی عملیات چککردن دسترسی، اگر کاربر جاری ایجادکننده پست نباشد، اینگونه درنظر گرفته میشود که وی مجوز «اصلاح پست» را ندارد.
هر دو گزینه «نقش» و «مجوز» میتوانند بصورت سلسلهمراتبی مشخصشوند. بطور خاص، یک نقش ممکناست شامل چند مجوز یا نقشهای دیگر باشد؛ و یک مجوز ممکن است شامل مجوز دیگری نیز باشد. Yii یک سیستم سلسله مراتبی «ترتیبی جزئی» را پیادهسازی کرده است که شامل یک سلسله مراتب خاصتر «درختی» است؛ بدینترتیب که ممکناست یک نقش شامل یک مجوز باشد اما عکس آن امکانپذیر نیست.
تنظیم RBAC
قبل از اینکه دادههای اعتبارسنجی را مشخصکنیم و بررسی دسترسی را انجامدهیم، باید کامپوننت [url=#$authManager-detail]authManager[/url] را تنظیم نماییم. Yii دو نوع مدیر اعتبارسنجی ارائه میدهد: yiirbacPhpManager و yiirbacDbManager. اولی از یک فایل PHP برای نگهداری اطلاعات اعتبارسنجی استفاده میکند، درحالیکه دومی این اطلاعات را در پایگاه دادهها ذخیره مینماید. اگر برنامه شما به مدیریت نقشها و مجوزهای آنچنان پویایی نیاز ندارد، میتوانید از اولی استفاده نمایید.
استفاده از PhpManager
کد زیر نحوه تنظیم authManager را در فایل تنظیمات برنامه با کمک کلاس yiirbacPhpManager نشان میدهد:
retu [
// ...
'components' => [
'authManager' => [
'class' => 'yiirbacPhpManager',
],
// ...
],
];
استفاده از DbManager
کد زیر نحوه تنظیم authManager را در فایل تنظیمات برنامه با استفاده از کلاس DbManager نشان میدهد:
retu [
// ...
'components' => [
'authManager' => [
'class' => 'yiirbacDbManager',
],
// ...
],
];
yii migrate --migrationPath=@yii/rbac/migrationsحال میتوانید ازطریق Yii::$app->authManager به کامپوننت authManager دسترسی پیدا کنید.
ایجاد داده های اعتبارسنجی
ساخت دادههای اعتبارسنجی شامل اعمال زیر است:
namespace appcommands;
use Yii;
use yiiconsoleController;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
// add "createPost" permission
$createPost = $auth->createPermission('createPost');
$createPost->description = 'Create a post';
$auth->add($createPost);
// add "updatePost" permission
$updatePost = $auth->createPermission('updatePost');
$updatePost->description = 'Update post';
$auth->add($updatePost);
// add "author" role and give this role the "createPost" permission
$author = $auth->createRole('author');
$auth->add($author);
$auth->addChild($author, $createPost);
// add "admin" role and give this role the "updatePost" permission
// as well as the permissions of the "author" role
$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $updatePost);
$auth->addChild($admin, $author);
// Assign roles to users. 1 and 2 are IDs retued by IdentityInterface::getId()
// usually implemented in your User model.
$auth->assign($author, 2);
$auth->assign($admin, 1);
}
}
public function signup()
{
if ($this->validate()) {
$user = new User();
$user->useame = $this->useame;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
$user->save(false);
// the following three lines were added:
$auth = Yii::$app->authManager;
$authorRole = $auth->getRole('author');
$auth->assign($authorRole, $user->getId());
retu $user;
}
retu null;
}
استفاده از قوانین
همانگونه که قبلاً ذکر شد، قوانین میتوانند قیدهای اضافهای به نقشها و مجوزها اضافه کنند. یک قانون، یک کلاس است که از yiirbacRule مشتق شده است. این کلاس باید متد execute() را پیادهسازی کند. در ساختار سلسلهمراتبی که قبلاً نوشته بودیم، author نمیتوانست پست خودش را ویرایش کند. اجازه دهید این موضوع را حل کنیم. اول نیاز به یک قانون داریم که مشخص میکند کاربر، ایجادکننده پست است:
namespace apprbac;
use yiirbacRule;
/**
* Checks if authorID matches user passed via params
*/
class AuthorRule extends Rule
{
public $name = 'isAuthor';
/**
* @param string|integer $user the user ID.
* @param Item $item the role or permission that this rule is associated with
* @param array $params parameters passed to ManagerInterface::checkAccess().
* @retu boolean a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
retu isset($params['post']) ? $params['post']->createdBy == $user : false;
}
}
$auth = Yii::$app->authManager;
// add the rule
$rule = new apprbacAuthorRule;
$auth->add($rule);
// add the "updateOwnPost" permission and associate the rule with it.
$updateOwnPost = $auth->createPermission('updateOwnPost');
$updateOwnPost->description = 'Update own post';
$updateOwnPost->ruleName = $rule->name;
$auth->add($updateOwnPost);
// "updateOwnPost" will be used from "updatePost"
$auth->addChild($updateOwnPost, $updatePost);
// allow "author" to update their own posts
$auth->addChild($author, $updateOwnPost);
بررسی دسترسی
حال که دادههای اعتبارسنجی آماده است، چککردن دسترسی به سادگی فراخوانی متد yiirbacManagerInterface::checkAccess() است. از آنجا که اغلب بررسیهای دسترسی درمورد کاربر جاری انجام میشود، برای راحتی بیشتر Yii یک متد میانبر بنام yiiwebUser::can() ارائه کرده است، که میتواند بصورت زیر بکار گرفته شود:
if (Yii::$app->user->can('createPost')) {
// create post
}
استفاده از نقشهای پیشفرض
یک نقش پیشفرض نقشی است که بصورت ضمنی به همه کاربران داده میشود. فراخوانی متد yiirbacManagerInterface::asign() نیاز نیست، و دادههای اعتبارسنجی شامل اطلاعات انتساب آن به کاربران نیستند.
یک نقش پیشفرض معمولاً با یک قانون مرتبط است که مشخص میکند نقش به کاربر مورد بررسی اختصاص مییابد یا خیر؟
نقشهای پیشفرض اغلب در برنامههایی بکار میروند که از قبل نقشهایی به کاربران داده شده است. برای مثال، یک برنامه ممکن است یک ستون «group» در جدول کاربرانش داشته باشد که نشان میدهد هر کاربر عضو کدام گروه مجوزهاست. اگر هر گروه مجوز را به یک نقش RBAC نگاشت کنیم، میتوانید از قابلیت نقش پیشفرض برای اختصاص خودکار هر کاربر به یک نقش RBAC استفاده کنید. اجازهدهید از یک مثال برای نمایش روش انجام این کار استفاده کنیم.
فرضکنید در جدول کاربران، یک ستون group دارید که از عدد 1 برای گروه مدیران و عدد 2 برای گروه نویسندگان استفاده میکند. شما میخواهید دو نقش admin و author را در RBAC برای نمایش مجوزهای این دو گروه استفاده نمایید. میتوانید RBAC را بهشکل زیر پیادهسازی کنید:
namespace apprbac;
use Yii;
use yiirbacRule;
/**
* Checks if user group matches
*/
class UserGroupRule extends Rule
{
public $name = 'userGroup';
public function execute($user, $item, $params)
{
if (!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->group;
if ($item->name === 'admin') {
retu $group == 1;
} elseif ($item->name === 'author') {
retu $group == 1 || $group == 2;
}
}
retu false;
}
}
$auth = Yii::$app->authManager;
$rule = new apprbacUserGroupRule;
$auth->add($rule);
$author = $auth->createRole('author');
$author->ruleName = $rule->name;
$auth->add($author);
// ... add permissions as children of $author ...
$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
$auth->addChild($admin, $author);
// ... add permissions as children of $admin ...
retu [
// ...
'components' => [
'authManager' => [
'class' => 'yiirbacPhpManager',
'defaultRoles' => ['admin', 'author'],
],
// ...
],
];
برچسب:
نویسنده: خنجی