RbacMiddleware: контроль доступа к маршрутам

Документ описывает работу RbacMiddleware — второго middleware в пайплайне запроса (после PassportAuthMiddleware).

1. Поток

flowchart TD
    A[Запрос, identity установлен] --> B{OPTIONS?}
    B -- да --> Z[Пропуск]
    B -- нет --> C{public route?}
    C -- да --> Z
    C -- нет --> D{найдено правило в permission_rules?}
    D -- нет --> E[403 PermissionDenied: RBAC policy is not defined]
    D -- да --> F{identity есть?}
    F -- нет --> G[401 Unauthorized]
    F -- да --> H[buildContext: mode, subjectUserId, subjectResolved]
    H --> I[authorizeForIdentity permission + context]
    I -- отказ --> J[403 PermissionDeniedException]
    I -- ок --> K{policy = role-assignment?}
    K -- да --> L[authorizeRoleAssignment]
    L -- нарушение --> J
    K -- нет --> Z
    L -- ок --> Z

2. Public routes

Список из params.php (public_routes), формат 'МЕТОД шаблон':

GET /            GET /auth/*       GET /gii       GET /debug      GET /debug/*
GET /docs        GET /docs/*       OPTIONS *      (и др.)

isPublic() поддерживает:

3. Правила (permission_rules)

Формат элемента:

[
    'method'     => 'GET',                        // HTTP-метод
    'pattern'    => '~^/users/(?<userId>\d+)$~',  // regex пути
    'permission' => 'users.read',                 // логическое разрешение
    'subject'    => [                             // опционально
        'mode'   => 'self-or-any',                // any | self-or-any | owner-only
        'source' => 'path',                       // path | query | body | owner
        'key'    => 'userId',                     // имя параметра/переменной
        // для owner: 'ownerKey' => 'id' (паттерн-группа)
    ],
    'policy'     => 'role-assignment',            // опционально: спец. политика
]

Примеры (из params.php)

['method' => 'GET',  'pattern' => '~^/users$~', 'permission' => 'users.list'],
[
    'method' => 'GET',
    'pattern' => '~^/users/(?<userId>\\d+)$~',
    'permission' => 'users.read',
    'subject' => ['mode' => 'self-or-any', 'source' => 'path', 'key' => 'userId'],
],
['method' => 'POST', 'pattern' => '~^/user-roles$~', 'permission' => 'user_roles.manage', 'policy' => 'role-assignment'],
['method' => 'GET',  'pattern' => '~^/rbac/permissions$~', 'permission' => 'rbac.permissions.manage'],

4. buildContext()

Собирает контекст для AuthorizationService:

ПолеИсточник
userIdYiiIdentity->getId() (если isUser)
subjectUserIdпо subject.source: path → группа regex (key), query → Yii::$app->request->get(key), body → body param (key), owner → subjectResolver->resolveOwner(['resource'=>key,'id'=>...])
subjectResolvedtrue/false (для owner: false, если владелец не определён)
modesubject.mode (любой)

5. authorizeRoleAssignment (policy)

Вызывается только для правил с 'policy' => 'role-assignment' (POST /user-roles, DELETE /user-roles/):

При нарушении → PermissionDeniedException('Role hierarchy violation').

6. Ошибки

СитуацияОтвет
Нет правила для маршрута403 RBAC policy is not defined for this route
Нет identity401 Authentication required
Нет разрешения403 Permission denied: <permission> + details
Нарушение role-assignment403 Role hierarchy violation

7. Связь с PermissionController / RolePermissionController