Аутентификация
Корпоративное программное обеспечение требует реализации многопользовательского режима и разделения прав доступа для пользователей. WT-платформа поддерживает механизмы аутентификации и авторизации, разделения пользователей на группы и настройки прав доступа.
В этот статье рассматривается процесс аутентификации, а правам доступа посвящена одноименная стать.
Список пользователей
Для начала рассмотрим, как представлен список пользователей в базе данных.
В базе данных в таблице public.user хранится общий список пользователей системы:

Описание полей таблицы:
user_id - идентификатор глобального пользователя;
user_name - логин глобального пользователя;
user_full_name - полное имя глобального пользователя;
person - признак, определяющий, является ли данный глобальный пользователь реальным пользователем;
enabled - признак, определяющий, является ли данный глобальный пользователь включенным;
language_id - идентификатор языка глобального пользователя;
time_zone_info_id - идентификатор временной зоны глобального пользователя;
user_password - хеш пароля глобального пользователя.
В таблице есть записи системных пользователей:
Служба Workflow Engine ($workflow_engine$) - системный пользователь службы Workflow Engine, от имени которого совершаются некоторые автоматические действия с данными в базе данных;
WS. Гость (WS_GUEST) - системный пользователь, под которым запускается клиентское приложение.
Пользователи Администратор, Пользователь 1 и Пользователь 2 - реальный пользователь, под которым можно работать в программе. Реальный пользователь Пользователь 3 отключен (enabled = false) и под ним нельзя будет работать в WT-программе.
Таблица template.user содержит идентификаторы пользователей, которые имеют доступ к бизнес-процессу Template:

Так же в эту таблицу можно добавить поля для индивидуальных пользовательских настроек, например, для доступа к какому-нибудь отчету.
Процесс аутентификации
Как происходит аутентификация и авторизация в WT-программе
1. Форма входа
Когда пользователь запускает программу, открывается форма входа в программу:

Где в выпадающем списке отображается список активных учеток пользователей, не являющихся системными и не принадлежащих группе GuestGroup.
2. Запрос на список пользователей
Когда открывается форма аутентификации, на сервер отправляется запрос на получение списка пользователей. Все запросы к серверу подписываются учеткой текущего пользователя программы. Так как вход в программу еще не осуществлен, то запрос на список активных пользователей подписывается гостевой учеткой WS_GUEST, логин и пароль которой указаны в конфиге клиентской части (WorkflowForms.dll.config).
Список пользователей формируется с помощью SQL-запроса вида:
<SqlQuery Name="UserLoginSelectSqlQuery">
<Text>
SELECT
user_id AS "UserId",
user_name AS "UserName",
user_full_name AS "UserFullName"
FROM
template.user_info UI
JOIN template.user_group UG USING(user_id)
JOIN template.group G USING (group_id)
WHERE
UI.person AND NOT UI.archive AND
G.name IS DISTINCT FROM 'GuestGroup';
</Text>
</SqlQuery>
В запросе используется template.user_info - это представление, которое динамически строится на основе двух таблиц: template.user и public.user.
3. Команда входа
На форме входа пользователь выбирает в выпадающем списке свою учетку и вводит пароль. По кнопке "Войти", клиентская часть хеширует введенный пароль безопасным алгоритмом SHA-512 и отправляет на сервер запрос с логином и хешом пароля в зашифрованном виде, используя для этого команду типа LoginCommand .
4. Аутентификация на сервере
Когда запрос приходит на сервер, он попадает сначала в веб-сервер Kestrel, на котором запущена веб-служба, а затем перенаправляется в серверное приложение.
На сервере механизм аутентификации и авторизации реализован с помощью JWT-токенов. Когда Workflow Engine получает запрос на аутентификацию пользователя, полученные логин и хеш пароля сверяются с теми, которые хранятся в таблице public.user в базе данных. Если логин и хеш пароля совпали - генерируется JWT-токен, который возвращается клиентскому приложению вместе с временем жизни этого токена и одноразовым токеном для повторной генерации основного JWT-токена.
5. Использование токенов
Клиентское приложение хранит JWT-токен и подписывает им все последующие запросы к серверу. Так же клиентская часть сама отслеживает время жизни JWT-токена: если JWT-токен устарел, то отправит запрос на обновление основного JWT-токена.
6. Авторизация на сервере при запросе
Сервер, получив запрос от клиентской части, проверяет JWT-токен, которым подписан запрос. Если токен актуален, то авторизация считается успешной, и происходит проверка Прав доступа у пользователя на выполнение запроса или команды.
Last updated