Special topics: authentication and authorization | the definitive guide to yii 1.1 | yii php framework

Контроль доступа на основе ролей (rbac)

Управление доступом на основе ролей (RBAC) обеспечивает простой, но мощный централизованный контроль доступа.
Пожалуйста, обратитесь к Wikipedia
для получения информации о сравнении RBAC с другими, более традиционными, системами контроля доступа.

Yii реализует общую иерархическую RBAC, следуя NIST RBAC model.
Обеспечивается функциональность RBAC через компонент приложения [[yiirbacManagerInterface|authManager]].

Использование RBAC состоит из двух частей. Первая часть — это создание RBAC данных авторизации, и вторая часть — это
использование данных авторизации для проверки доступа в том месте, где это нужно.

Для облегчения последующего описания, мы сначала введём некоторые основные понятия RBAC.

Основные концепции

Роль представляет собой набор разрешений (permissions) (например, создание сообщения, обновление сообщения).
Роль может быть назначена на одного или многих пользователей. Чтобы проверить, имеет ли пользователь указанные
разрешения, мы должны проверить, назначена ли пользователю роль, которая содержит данное разрешение.

С каждой ролью или разрешением может быть связано правило (rule). Правило представляет собой кусок кода, который будет
выполняться в ходе проверки доступа для определения может ли быть применена соответствующая роль или разрешение
к текущему пользователю.

Например, разрешение “обновление поста” может иметь правило, которое проверяет является ли
текущий пользователь автором поста. Во время проверки доступа, если пользователь не является автором поста, он/она будет
считаться не имеющими разрешения “обновление поста”.

И роли, и разрешения могут быть организованы в иерархию. В частности, роль может содержать другие роли или разрешения; и
разрешения могут содержать другие разрешения. Yii реализует частично упорядоченную иерархию, которая включает в себя
специальные деревья иерархии. Роль может содержать разрешение, но обратное не верно.

Role-Based Access Control ¶

Role-Based Access Control (RBAC) provides a simple yet powerful
centralized access control. Please refer to the Wiki
article for more
details about comparing RBAC with other more traditional access control
schemes.

Yii implements a hierarchical RBAC scheme via its
authManager application component. In the
following ,we first introduce the main concepts used in this scheme; we
then describe how to define authorization data; at the end we show how to
make use of the authorization data to perform access checking.

Yii: аутентификация и авторизация |

Основные моменты аутентификации и авторизации в Yii.

Аутентификация — идентификация, установление личности (идентичности, identity) пользователя, ввод логина и пароля.

Авторизация — проверка прав уже идентифицированного пользователя (или анонимного) на доступ к данным.

Identity — индивидуальность, идентичность, подлинность, тождественность, личность.

Для аутентификации в Yii используются:

В настройках компонента user (в конфигурации) нужно указать identityClass — класс, который будет содержать логику аутентификации. Как правило это класс модели, представляющий пользователя. Этот класс должен реализовывать интерфейс yiiwebIdentityInterface.

Интерфейс yiiwebIdentityInterface включает следующие методы:

Реализовывать все методы не обязательно, не нужные можно оставить с пустым телом. В простых MVC приложениях используются методы findIdentity(), getAuthKey(), validateAuthKey() и getId(), в REST приложениях — findIdentityByAccessToken() и getId().

Класс, реализующий интерфейс yiiwebIdentityInterface, может одновременно наследоваться от ActiveRecord.

В контроллерах можно использовать статические методы и свойства компонента user (yiiwebUser) для идентификации пользователя:

Yii2/rest-authentication.md at master · yiisoft/yii2

В отличие от веб-приложений, RESTful API обычно не сохраняют информацию о состоянии, а это означает, что сессии и куки
использовать не следует. Следовательно, раз состояние аутентификации пользователя не может быть сохранено в сессиях или куках,
каждый запрос должен приходить вместе с определенным видом параметров аутентификации. Общепринятая практика состоит в том,
что для аутентификации пользователя с каждым запросом отправляется секретный токен доступа. Так как токен доступа
может использоваться для уникальной идентификации и аутентификации пользователя, запросы к API всегда должны отсылаться
через протокол HTTPS, чтобы предотвратить атаки «человек посередине» (англ. “man-in-the-middle”, MitM)
.

Есть различные способы отправки токена доступа:

Yii поддерживает все выше перечисленные методы аутентификации. Вы также можете легко создавать новые методы аутентификации.

Чтобы включить аутентификацию для ваших API, выполните следующие шаги:

  1. У компонента приложенияuser установите свойство
    [[yiiwebUser::enableSession|enableSession]] равным false.
  2. Укажите, какие методы аутентификации вы планируете использовать, настроив поведение authenticator
    в ваших классах REST-контроллеров.
  3. Реализуйте метод [[yiiwebIdentityInterface::findIdentityByAccessToken()]] в вашем [[yiiwebUser::identityClass|классе UserIdentity]].

Шаг 1 не обязателен, но рекомендуется его всё-таки выполнить, так как RESTful API не должен сохранять информацию о
состоянии клиента. Когда свойство [[yiiwebUser::enableSession|enableSession]] установлено в false, состояние
аутентификации пользователя НЕ БУДЕТ сохраняться между запросами с использованием сессий. Вместо этого аутентификация
будет выполняться для каждого запроса, что достигается шагами 2 и 3.

Tip: если вы разрабатываете RESTful API в пределах приложения, вы можете настроить свойство
[[yiiwebUser::enableSession|enableSession]] компонента приложения user в конфигурации приложения. Если вы
разрабатываете RESTful API как модуль, можете добавить следующую строчку в метод init() модуля:

Например, для использования HTTP Basic Auth, вы можете настроить свойство authenticator следующим образом:

Если вы хотите включить поддержку всех трёх описанных выше методов аутентификации, можете использовать CompositeAuth:

Каждый элемент в массиве authMethods должен быть названием класса метода аутентификации или массивом настроек.

Реализация метода findIdentityByAccessToken() определяется особенностями приложения. Например, в простом варианте,
когда у каждого пользователя есть только один токен доступа, вы можете хранить этот токен в поле access_token
таблицы пользователей. В этом случае метод findIdentityByAccessToken() может быть легко реализован в классе User следующим образом:

После включения аутентификации описанным выше способом при каждом запросе к API запрашиваемый контроллер
будет пытаться аутентифицировать пользователя в своем методе beforeAction().

Если аутентификация прошла успешно, контроллер выполнит другие проверки (ограничение частоты запросов, авторизация)
и затем выполнит действие. Информация об аутентифицированном пользователе может быть получена из объекта Yii::$app->user->identity.

Если аутентификация прошла неудачно, будет возвращен ответ с HTTP-кодом состояния 401 вместе с другими необходимыми заголовками
(такими, как заголовок WWW-Authenticate для HTTP Basic Auth).

После аутентификации пользователя вы, вероятно, захотите проверить, есть ли у него или у неё разрешение на выполнение запрошенного
действия с запрошенным ресурсом. Этот процесс называется авторизацией и подробно описан
в разделе «Авторизация».

Если ваши контроллеры унаследованы от [[yiirestActiveController]], вы можете переопределить
метод [[yiirestController::checkAccess()|checkAccess()]] для выполнения авторизации. Этот метод будет вызываться
встроенными действиями, предоставляемыми контроллером [[yiirestActiveController]].

Использование правил

Как упомянуто выше, правила добавляют дополнительные ограничения на роли и разрешения. Правила — это классы, расширяющие
[[yiirbacRule]]. Они должны реализовывать метод [[yiirbacRule::execute()|execute()]]. В иерархии, созданной нами ранее,
автор не может редактировать свой пост. Давайте исправим это. Сначала мы должны создать правило, проверяющее
что пользователь является автором поста:

Использование роли по умолчанию

Роль по умолчанию — это роль, которая неявно присваивается всем пользователям. Вызов метода
[[yiirbacManagerInterface::assign()]] не требуется, и авторизационные данные не содержат информации о назначении.

Роль по умолчанию обычно связывают с правилом, определяющим к какой роли принадлежит каждый пользователь.

Роли по умолчанию обычно используются в приложениях, которые уже имеют какое-то описание ролей. Для примера, приложение
может иметь столбец “group” в таблице пользователей, и каждый пользователь принадлежит к какой-то группе. Если каждая
группа может быть сопоставлена роли в модели RBAC, вы можете использовать роль по умолчанию для автоматического назначения
каждому пользователю роли RBAC. Давайте используем пример, чтобы понять как это можно сделать.

Как сделать авторизацию и регистрацию в yii2 basic

<?php

namespaceappmodels;

useYii;

useyiibaseNotSupportedException;

useyiibehaviorsTimestampBehavior;

useyiidbActiveRecord;

useyiiwebIdentityInterface;

/**

* User model

*

* @property integer $id

* @property string $username

* @property string $password_hash

* @property string $password_reset_token

* @property string $email

* @property string $auth_key

* @property integer $status

* @property integer $created_at

* @property integer $updated_at

* @property string $password write-only password

*/

classUserextendsActiveRecordimplementsIdentityInterface

{

    constSTATUS_DELETED=0;

    constSTATUS_ACTIVE=10;

    /**

     * @inheritdoc

     */

    publicstaticfunctiontableName()

    {

        return‘{{%user}}’;

    }

    /**

     * @inheritdoc

     */

    publicfunctionbehaviors()

    {

        return[

            TimestampBehavior::className(),

        ];

    }

    /**

     * @inheritdoc

     */

    publicfunctionrules()

    {

        return[

            [‘status’,‘default’,‘value’=>self::STATUS_ACTIVE],

            [‘status’,‘in’,‘range’=>[self::STATUS_ACTIVE,self::STATUS_DELETED]],

        ];

    }

    /**

     * @inheritdoc

     */

    publicstaticfunctionfindIdentity($id)

    {

        returnstatic::findOne([‘id’=>$id,‘status’=>self::STATUS_ACTIVE]);

    }

    /**

     * @inheritdoc

     */

    publicstaticfunctionfindIdentityByAccessToken($token,$type=null)

    {

        thrownewNotSupportedException(‘”findIdentityByAccessToken” is not implemented.’);

    }

    /**

     * Finds user by username

     *

     * @param string $username

     * @return static|null

     */

    publicstaticfunctionfindByUsername($username)

    {

        returnstatic::findOne([‘username’=>$username,‘status’=>self::STATUS_ACTIVE]);

    }

    /**

     * @inheritdoc

     */

    publicfunctiongetId()

    {

        return$this->getPrimaryKey();

    }

    /**

     * @inheritdoc

     */

    publicfunctiongetAuthKey()

    {

        return$this->auth_key;

    }

    /**

     * @inheritdoc

     */

    publicfunctionvalidateAuthKey($authKey)

    {

        return$this->getAuthKey()===$authKey;

    }

    /**

     * Validates password

     *

     * @param string $password password to validate

     * @return bool if password provided is valid for current user

     */

    publicfunctionvalidatePassword($password)

    {

        returnYii::$app->security->validatePassword($password,$this->password_hash);

    }

    /**

     * Generates password hash from password and sets it to the model

     *

     * @param string $password

     */

    publicfunctionsetPassword($password)

    {

        $this->password_hash=Yii::$app->security->generatePasswordHash($password);

    }

    /**

     * Generates “remember me” authentication key

     */

    publicfunctiongenerateAuthKey()

    {

        $this->auth_key=Yii::$app->security->generateRandomString();

    }

//ВОССТАНОВЛЕНИЕ ПАРОЛЯ

publicstaticfunctionfindByPasswordResetToken($token)

{

if(!static::isPasswordResetTokenValid($token)){

returnnull;

}

returnstatic::findOne([

‘password_reset_token’=>$token,

‘status’=>self::STATUS_ACTIVE,

]);

}

publicstaticfunctionisPasswordResetTokenValid($token)

{

if(empty($token)){

returnfalse;

}

$timestamp=(int)substr($token,strrpos($token,‘_’) 1);

$expire=Yii::$app->params[‘user.passwordResetTokenExpire’];

return$timestamp $expire>=time();

}

publicfunctiongeneratePasswordResetToken()

{

$this->password_reset_token=Yii::$app->security->generateRandomString().‘_’.time();

}

publicfunctionremovePasswordResetToken()

{

$this->password_reset_token=null;

}

}

Настройка authmanager с помощью dbmanager

Следующий код показывает как настроить в конфигурации приложения authManager с использованием класса [[yiirbacDbManager]]:

return [
    'components' => [
        'authManager' => [
            'class' => 'yiirbacDbManager',
        ],
        
    ],
];

DbManager использует четыре таблицы для хранения данных:

  • [[yiirbacDbManager::$itemTable|itemTable]]: таблица для хранения авторизационных элементов. По умолчанию “auth_item”.
  • [[yiirbacDbManager::$itemChildTable|itemChildTable]]: таблица для хранения иерархии элементов. По умолчанию “auth_item_child”.
  • [[yiirbacDbManager::$assignmentTable|assignmentTable]]: таблица для хранения назначений элементов авторизации. По умолчанию “auth_assignment”.
  • [[yiirbacDbManager::$ruleTable|ruleTable]]: таблица для хранения правил. По умолчанию “auth_rule”.

Прежде чем вы начнёте использовать этот менеджер, вам нужно создать таблицы в базе данных. Чтобы сделать это,
вы можете использовать миграцию хранящуюся в файле @yii/rbac/migrations:

yii migrate [email protected]/rbac/migrations

Теперь authManager может быть доступен через Yii::$app->authManager.

Настройка authmanager с помощью phpmanager

Следующий код показывает как настроить в конфигурации приложения authManager с использованием класса [[yiirbacPhpManager]]:

return [
    'components' => [
        'authManager' => [
            'class' => 'yiirbacPhpManager',
        ],
        
    ],
];

Теперь authManager может быть доступен через Yii::$app->authManager.

Замечание: По умолчанию, [[yiirbacPhpManager]] сохраняет данные RBAC в файлах в директории @app/rbac/. Убедитесь
что данная директория и файлы в них доступны для записи Web серверу, если иерархия разрешений должна меняться онлайн.

Настройка rbac manager

Перед определением авторизационных данных и проверкой прав доступа, мы должны настроить компонент приложения
[[yiibaseApplication::authManager|authManager]]. Yii предоставляет два типа менеджеров авторизации:
[[yiirbacPhpManager]] и [[yiirbacDbManager]].

Разграничение прав в rest api на yii2

Разграничение прав доступа для REST API ничем не отличается от разграничений прав в обычном приложении. Так как я уже подробно описывала RBAC в Yii2, повторяться не буду.

$behaviors[ 'access'] = [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
            ],
        ];

Если остались вопросы — задавайте их в комментариях, а я постараюсь на них ответить.

Создание данных авторизации

Для создания данных авторизации нужно выполнить следующие задачи:

  • определение ролей и разрешений;
  • установка отношений между ролями и правами доступа;
  • определение правил;
  • связывание правил с ролями и разрешениями;
  • назначение ролей пользователям.

В зависимости от требований к гибкости авторизации перечисленные задачи могут быть выполнены разными путями.

Если иерархия прав не меняется, и количество пользователей зафиксировано, вы можете создать
консольную команду, которая будет единожды инициализировать данные
через APIs, предоставляемое authManager:

Три способа аутентификации в yii2

Yii2 реализовано 3 класса для аутентификации пользователя:

Фильтры контроля доступа

Фильтры контроля доступа (ACF) являются простым методом, который лучше всего использовать в приложениях с простым
контролем доступа. Как видно из их названия, ACF — это фильтры, которые могут присоединяться к контроллеру
или модулю как поведение. ACF проверяет набор [[yiifiltersAccessControl::rules|правил доступа]], чтобы убедиться,
что пользователь имеет доступ к запрошенному действию.

Код ниже показывает, как использовать ACF фильтр, реализованный в [[yiifiltersAccessControl]]:

useyiifiltersAccessControl;

classSiteControllerextendsController{
    publicfunctionbehaviors(){
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['login', 'logout', 'signup'],
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['login', 'signup'],
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['logout'],
                        'roles' => ['@'],
                    ],
                ],
            ],
        ];
    }
    
}

Код выше показывает ACF фильтр, связанный с контроллером site через поведение. Это типичный способ использования фильтров действий.
Параметр only указывает, что фильтр ACF нужно применять только к действиям login, logout и signup.
Параметр rules задаёт [[yiifiltersAccessRule|правила доступа]], которые означают следующее:

  • Разрешить всем гостям (ещё не прошедшим авторизацию) доступ к действиям login и signup.
    Опция roles содержит знак вопроса ?, это специальный токен обозначающий “гостя”.
  • Разрешить аутентифицированным пользователям доступ к действию logout. Символ @ — это другой специальный токен,
    обозначающий аутентифицированного пользователя.

Когда фильтр ACF проводит проверку авторизации, он проверяет правила по одному сверху вниз, пока не найдёт совпадение.
Значение опции allow выбранного правила указывает, авторизовывать пользователя или нет. Если ни одно из правил
не совпало, то пользователь считается НЕавторизованным, и фильтр ACF останавливает дальнейшее выполнение действия.

По умолчанию, когда у пользователя отсутствует доступ к текущему действию, ACF делает следующее:

Вы можете переопределить это поведение, настроив свойство [[yiifiltersAccessControl::denyCallback]]:

[
    'class' => AccessControl::className(),
    'denyCallback' => function($rule, $action){
        thrownew Exception('У вас нет доступа к этой странице');
    }
]

[[yiifiltersAccessRule|Правила доступа]] поддерживают набор свойств. Ниже дано краткое описание поддерживаемых опций.
Вы также можете расширить [[yiifiltersAccessRule]], чтобы создать свой собственный класс правил доступа.

Похожее:  Личный кабинет «Карусели» 🏷️ | Вход по номеру

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *