Как плагин CakePHP Authorization может разрешить доступ к индексам? - PullRequest
0 голосов
/ 29 октября 2018

Я конвертирую свое приложение в CakePHP 3.6 и сейчас работаю над использованием нового плагина авторизации. Я не уверен, как проверить авторизацию для таких вещей, как индексы или другие отчеты, где нет «ресурса» для передачи в функции can() или authorize().

На данный момент я создал ControllerResolver, свободно скопированный из ORMResolver, который принимает объекты контроллера и находит политики на основе имени единого контроллера, так что они называются так же, как политики Entity I строю. (То есть мой 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 для этого, если это просто недосмотр.

Но авторизация индексов кажется довольно очевидной функцией, поэтому мне интересно, что я что-то пропустил. Может быть, я должен передать объект таблицы и разделить авторизацию между политикой объекта и политикой таблицы? Но использование табличных объектов в представлениях только для этой цели кажется нарушением разделения интересов. Может быть, использование плагина на сегодняшний день было вещами, где индексы всегда общедоступны?

1 Ответ

0 голосов
/ 27 ноября 2018

для этого вы можете использовать authorizeModel, как указано в документации https://github.com/cakephp/authorization/blob/master/docs/Component.md#automatic-authorization-checks. По сути, это добавление параметров auhtorizeModel при загрузке компонента в AppController.php

$this->loadComponent('Authorization.Authorization', [
    'skipAuthorization' => ['login','token'],
    'authorizeModel' => ['index','add'],
]);

Когда вы настраиваете действие для авторизации по модели, служба авторизации использует TablePolicy, поэтому, если вы хотите авторизовать действие индекса для книг, вам нужно создать 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));
}
...