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

Перевоплощение (Impersonation)

Источники: core (AuthController, PermissionsService, TokenModificationsService, TransformationLogEntity), архивное руководство администратора: alien.md

1. Что это

Перевоплощение — механизм, позволяющий администратору (или пользователю с соответствующими правами) работать в системе от имени другого пользователя. Видит то же, что видит целевой пользователь. Используется для отладки прав, настройки UI, поддержки.

Не путать с замещением — замещение передаёт права, перевоплощение создаёт новую сессию от имени целевого пользователя. См. substitution.md.

2. Кто может перевоплощаться

Три способа получить право:

# Способ Условие
1 Системная группа «Администраторы» Пользователь в группе Administrators И группе не выдано спецправо DENYIMPERSONATION
2 Право группы на группу Право «Перевоплощаться в членов группы» (ActionID = Helpers.ActionsGroupOnGroup.Impersonate). Не-админ → не может перевоплощаться в админа
3 EWS (Exchange) Для синхронизации календаря. Настройка CalendarExchangeUseImpersonate или общая настройка «Использовать перевоплощение»

Алгоритм проверки (PermissionsService.CanImpersonate)

1. CheckSpecialPermission(userId, DENYIMPERSONATION) → true? → return false
2. IsUserGod(userId) → true? → return true  (админ может в любого)
3. IsUserGod(targetUserId) → true? → return false  (не-админ не может в админа)
4. CheckUserOnUserPermission(userId, targetUserId, Impersonate) → проверка прав группы на группу

Код: core/TCClassLib/Permissions/PermissionsService.cs:213-235

3. Спецправо DENYIMPERSONATION

Специальное право, назначаемое группе. Если пользователь входит хотя бы в одну группу с этим правом — перевоплощение для него запрещено (даже если он администратор).

Ограничение: нельзя назначить DENYIMPERSONATION группе «Администраторы».

Мнемоника: DENYIMPERSONATION в таблице GroupPermissionsToSpecialActions.

Код: core/Valhalla.Integration/Constants/SpecialActions.cs:65, AdminPermissionsService.cs:77-107

4. API

4.1 Начать перевоплощение

POST /api/auth/{userId}/impersonate

Ответы: - 204 No Content — успешно, последующие запросы от имени целевого пользователя - 403 Forbidden — нет прав или попытка вложенного перевоплощения

Ограничение: вложенное перевоплощение запрещено. Если Context.ImpersonatedUserId.HasValue — возвращается 403.

Код: core/UniForm/UniForm.Api/Controllers/OldApi/Version2_0/Auth/AuthController.cs:290-317

4.2 Завершить перевоплощение

POST /api/auth/undotransformation

Ответ: 204 No Content — сессия возвращается к реальному пользователю.

Код: AuthController.cs:330-344

5. Механика сессии (JWT)

При перевоплощении: 1. UserAuthenticationService.Impersonate(HttpContext, userId) — создаёт новый JWT 2. В новом JWT: SessionUserId = целевой пользователь, OldUserId = инициатор 3. Поле Context.ImpersonatedUserId доступно всем сервисам для проверки «кто инициатор» 4. Все действия выполняются от имени целевого пользователя 5. При StopImpersonation — JWT возвращается к исходному пользователю 6. Проверяется наличие действующей лицензии у целевого пользователя. Если лицензия отсутствует, перевоплощение не выполняется. 7. JWT перевыпускается уже после успешного прохождения этой проверки.

6. Аудит (TransformationLog)

Каждое перевоплощение логируется в таблицу TransformationLog.

Колонка Тип Описание
TransformationLogID int, PK, Identity ID записи
OldUserID int, FK → Users Инициатор перевоплощения
NewUserID int, FK → Users Целевой пользователь
TransformationTime datetime Время события
UserComputerName varchar(300) Hostname / IP инициатора
IsReturn bit 0 = перевоплощение, 1 = возврат
UserAgent varchar(512), NULL User-Agent браузера

Запись создаётся при: перевоплощении (IsReturn=0) и возврате (IsReturn=1).

Просмотр: вкладка «Журнал» в профиле пользователя. Видят: администраторы (в журналах всех), пользователь (в своём журнале).

Код: core/Valhalla.Authentication/Authentication/Token/Jwt/TokenModificationsService.cs:191-216

7. Защита данных при перевоплощении

7.1 Конфиденциальность

Перевоплощение НЕ блокируется конфиденциальностью. Администратор, перевоплотившись, видит конфиденциальные задачи целевого пользователя (если тот является подписчиком).

Это by design — конфиденциальность защищает от коллег, не от администратора.

7.2 Шифрование

Перевоплощение блокируется шифрованием. При перевоплощении проверяются права обоих — и инициатора, и целевого пользователя. Оба должны иметь право «Просмотр зашифрованных задач», чтобы увидеть расшифрованные данные.

Что скрыто при отсутствии прав у одного из двух: - Зашифрованные ДП — пустые / скрытые - Текст задачи — не отображается - Файлы — недоступны для скачивания - Комментарии — текст скрыт

Исторический баг (исправлен в 2.267.353): МТФ передавал null вместо oldSessionUserId → проверка шифрования обходилась. Исправлено в 103 файлах (backend + frontend).

7.3 Матрица

Защитный механизм Замещение Перевоплощение
Конфиденциальность Заблокировано Доступ есть
Шифрование Заблокировано Заблокировано (оба должны иметь право)
Конфиденциальность + шифрование Заблокировано Заблокировано

8. UI

В SPA

  • Кнопка перевоплощения: в профиле пользователя (панель инструментов) и в справочнике «Сотрудники» (при наведении)
  • Индикатор перевоплощения: зелёная полоса в верхней панели с именем целевого пользователя
  • Выход: крестик на индикаторе

В мобильном приложении

Перевоплощение доступно. Подробности: ../mobile/README.md.

9. Ограничения

Ограничение Описание
Вложенное перевоплощение Запрещено. Нельзя перевоплощаться, будучи перевоплощённым
Лицензия Для перевоплощения у целевого пользователя должна быть действующая лицензия (не-конкурентная). Проверка выполняется в TokenModificationsService.ChangeUser после CanImpersonate. Если лицензия отсутствует — перевоплощение блокируется.
Не-админ → админ Пользователь без прав God не может перевоплотиться в администратора
DENYIMPERSONATION Блокирует перевоплощение даже для администратора
Нельзя применить DENYIMPERSONATION к группе «Администраторы» Защита от самоблокировки

10. Связанная документация

  • substitution.md — замещение (передача прав, не сессии)
  • business.md §9 — конфиденциальность и шифрование
  • access-check.md — fn_UserTaskPermissionsGeneral (перевоплощение меняет @UserID)
  • архивной инструкции администратора по замещению — инструкция администратора
  • ../users-and-groups/faq-absence-button-visibility.md — специальные права групп

Не путать с системной impersonation для AI-агентов

1f-real-user-id — служебный HTTP-заголовок, через который аутентифицированный системный агент (Анфиса, server-side worker'ы) выполняет запрос от имени пользователя для применения ACL под этого пользователя. Это другой механизм:

User impersonation (этот документ) 1f-real-user-id
Кто использует Администратор через UI AI-агент / server-side worker через HTTP
Цель Отладка прав, поддержка Применение прав asker'а к read-операциям
Создаёт сессию Да (новый JWT с ImpersonatedUserId) Нет — per-request override SessionUserId
Логируется TransformationLogEntity На уровне tool-handler'а (AnfisaConversationLog)
API POST /api/auth/{userId}/impersonate Header в любом GET/POST с PAT/JWT

Спека 1f-real-user-id: reference/api/auth-operations-guide.md § 1.5. Применение в Анфисе: domains/ai/architecture/permission-enforcement.md.

11. Источники кода

Объект Файл
API endpoint core/UniForm/UniForm.Api/Controllers/OldApi/Version2_0/Auth/AuthController.cs:290
CanImpersonate core/TCClassLib/Permissions/PermissionsService.cs:213
DENYIMPERSONATION core/Valhalla.Integration/Constants/SpecialActions.cs:65
AdminPermissionsService core/TCClassLib/Permissions/AdminPermissionsService.cs:77
TransformationLogEntity core/TCDataAccess/Kernel/Domain/Entities/TransformationLogEntity.cs
JWT обработка core/Valhalla.Authentication/Authentication/Token/Jwt/TokenModificationsService.cs:191