Перейти к содержанию

Runbook: нет доступа к форме / ошибка авторизации

1. Когда использовать

Признаки инцидента:

  1. Пользователь видит Нет доступа к задаче или переходит на /error/403.
  2. Открытие задачи по ID не работает, хотя задача существует.
  3. Запросы к data source/форме возвращают 403 Forbidden.
  4. Есть жалобы на «ошибка авторизации» после логина/refresh токена.

2. Как это работает (по коду)

2.1 Контур аутентификации

  1. SPA получает токен через POST /api/auth/token-v2.
  2. Обновление сессии: POST /api/auth/token/refresh.
  3. Проверка текущей сессии: GET /api/auth/info.
  4. Глобально 403 перехватывается интерсептором и обычно ведет на /error/403 (кроме allowlist URL).

2.2 Проверка доступа к задаче перед открытием формы

  1. SPA вызывает GET /api/tasks/check-exist-and-access/{taskId}.
  2. Backend возвращает:
  3. IsTaskExists,
  4. IsUserHasAccess,
  5. TaskShortInfo.
  6. При IsTaskExists = true и IsUserHasAccess = false фронт формирует сообщение с owner/performers (noAccessToTheTask + accessDeniedMessage2).

2.3 Как рассчитывается CheckTaskAccess

TaskPermissionsService.CheckTaskAccess:

  1. Проверяет существование задачи.
  2. SystemRobot -> всегда true.
  3. Уволенный пользователь (IsFired) -> false.
  4. Для admin-контекстов (AdminDeleteContext/AdminDataSourceContext):
  5. либо God,
  6. либо Set-право на задачу.
  7. Для обычного контекста:
  8. подписка на задачу (TaskSubscriberInfoService) дает доступ,
  9. для конфиденциальной задачи доступ через замещение не расширяется,
  10. затем проверка через fn_UserTaskPermissions / fn_CheckUserTaskPermissions.

2.4 Data source-контур

DataSourceController при AccessDeniedException возвращает 403 (Forbid). Это отдельный уровень прав: пользователь может иметь базовый доступ к задаче, но не иметь доступ к конкретному source/action.

3. Что смотреть при разборе (чек-лист)

  1. Зафиксировать: userId, taskId, URL экрана, время, текст ошибки.
  2. Проверить аутентификацию:
  3. успешен ли auth/token-v2 или auth/token/refresh,
  4. возвращает ли auth/info корректного пользователя.
  5. Проверить tasks/check-exist-and-access/{taskId}:
  6. IsTaskExists = false -> это не доступ, а отсутствующая/некорректная задача,
  7. IsTaskExists = true, IsUserHasAccess = false -> чистый кейс прав.
  8. Если это 403 от data source:
  9. зафиксировать конкретный endpoint source,
  10. разделить проблему прав задачи и прав source.
  11. Проверить, не уволен ли пользователь, нет ли impersonation-эффекта.
  12. Проверить, не конфиденциальная ли задача (для таких задач замещение ограничено).
  13. Проверить факт подписки пользователя на задачу.
  14. Проверить fn_UserTaskPermissions/fn_CheckUserTaskPermissions по задаче.

4. Симптом -> вероятная причина -> проверка

Симптом Вероятная причина Что проверить первым
После логина сразу 401/403 невалидный access/refresh, истекла сессия auth/token-v2, auth/token/refresh, auth/info
Нет доступа к задаче при прямом открытии ID задача есть, но CheckTaskAccess=false tasks/check-exist-and-access/{taskId}
Только часть пользователей не открывает задачу role/subscriber различия UserTaskPermissions, подписка на задачу
Доступ к задаче есть, но source возвращает 403 нет прав на конкретный data source endpoint source + серверный AccessDeniedException
Через замещение доступ пропал на конкретных задачах задача конфиденциальная признак confidential + проверка access без замещения

5. SQL для быстрой диагностики

-- Входные параметры
-- @user_id int
-- @task_id int

-- Базовая информация по пользователю
select
        u.UserID,
        u.IsFired
from dbo.Users u
where u.UserID = @user_id;

-- Базовая информация по задаче
select
        t.TaskID,
        t.SubcatID,
        t.UserID as OwnerUserID
from dbo.Tasks t
where t.TaskID = @task_id;

-- Видит ли пользователь задачу через денормализованный контур прав
select top (1)
        utp.TaskID,
        utp.UserID
from dbo.UserTaskPermissions utp
where utp.TaskID = @task_id and
      utp.UserID = @user_id;

-- Проверка права через функцию (MS SQL путь)
select
        p.TaskID
from dbo.fn_CheckUserTaskPermissions(
        @task_id,
        @user_id,
        (
            select t.SubcatID
            from dbo.Tasks t
            where t.TaskID = @task_id
        )
) p;

-- Проверка подписки на задачу
select top (20)
        ms.TaskID,
        ms.UserID,
        ms.DateAdd
from dbo.MailSubscribers ms
where ms.TaskID = @task_id and
      ms.UserID = @user_id
order by
        ms.DateAdd desc;

6. Что приложить в задачу разработчикам

  1. userId, taskId, URL и шаги воспроизведения.
  2. Ответы auth/info и tasks/check-exist-and-access/{taskId}.
  3. Текст/скрин 403 (если от data source -- какой именно endpoint).
  4. SQL-снимок из блока выше.
  5. Было ли перевоплощение (impersonate) и повторяется ли проблема без него.

Связанные документы

  • docs/domains/auth/backend.md
  • docs/domains/tasks/backend.md
  • docs/domains/task-forms/README.md
  • docs/reference/security/auth-security-model.md