我正在将我的应用程序转换为CakePHP 3.6,现在正在使用新的Authorization插件进行工作。我不确定如何检查索引或其他报表之类的授权,在这些授权中没有“资源”传递给can()
或authorize()
函数。
现在,我已经构建了一个ControllerResolver
,是从ORMResolver
松散复制的,它可以接受控制器对象并根据单数的控制器名称查找策略,因此它们的命名与我正在建立的实体政策。 (也就是说,我的UserPolicy
可以具有canIndex
和canEdit
函数,前者是通过控制器找到的,后者是通过实体找到的。)
这在我可以调用$this->Authorize->authorize($this);
的控制器操作中很好用,但在视图中却无法工作,在视图中我希望能够执行以下操作:
if ($this->Identity->can('index', *something*)) {
echo $this->Html->link('List', ['action' => 'index']);
}
以便仅显示允许执行这些操作的人员的链接。
任何人都知道系统是否有隐式要求将传递到授权功能中的“资源”作为对象的原因吗? (例如,在授权失败的情况下,插件组件将调用get_class($resource)
,而无需先检查所提供的资源实际上是否是对象。)允许使用字符串(例如\App\Controller\UsersController::class
)可以使我的生活更美好简单。如果只是出于疏忽,很高兴为此准备一份PR。
但是授权索引似乎是一个很明显的功能,所以我想知道我是否错过了什么。也许我应该传递表对象,并在实体策略和表策略之间分配授权?但是仅出于此目的在视图中使用表对象似乎违反了关注点分离。也许到目前为止,该插件的使用一直是索引始终公开的事情?
答案 0 :(得分:1)
为此,您可以使用https://github.com/cakephp/authorization/blob/master/docs/Component.md#automatic-authorization-checks文档中所述的authorizeModel
。基本上是在AppController.php加载组件时添加auhtorizeModel参数
$this->loadComponent('Authorization.Authorization', [
'skipAuthorization' => ['login','token'],
'authorizeModel' => ['index','add'],
]);
当您配置要由模型授权的动作时,授权服务将使用TablePolicy,因此,如果要为Books授权索引动作,则需要创建BooksTablePolicy并实现方法
<?php
namespace App\Policy;
use App\Model\Table\BooksTable;
use Authorization\IdentityInterface;
/**
* Books policy
*/
class BooksTablePolicy
{
public function scopeIndex($user, $query)
{
return $query->where(['Books.user_id' => $user->id]);
}
public function canIndex(IdentityInterface $identity)
{
// here you can resolve true or false depending of the identity required characteristics
$identity['can_index']=true;
return $identity['can_index'];
}
}
这将在请求到达您的控制器之前进行验证,因此您无需在那里进行任何授权。不过,如果您想应用范围策略,如本例所示:
public function index()
{
$user = $this->request->getAttribute('identity');
$query = $user->applyScope('index', $this->Books->find()->contain('Users'));
$this->set('books', $this->paginate($query));
}