Аутентификация

Корпоративное программное обеспечение требует реализации многопользовательского режима и разделения прав доступа для пользователей. 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-приложение может объединять несколько программ для разных бизнес-процессов, например, для автомойки и шиномонтажа.

Каждая программа будет иметь свой набор xml-файлов форм и свой серверный xml-файл с запросами. И, в большинстве случаев, серверная часть у них будет одна - нет смысла специально разделать серверные части, если в этом нет потребности. А значит, и базу данных можно использовать одну, но для каждого бизнес-процесса делать отдельную схему, чтобы разделить таблицы и функции.

Несмотря на то, что автомойка и шиномонтаж разные программы, какие-то пользователи могут иметь доступ к обеим программам, например, администраторы. Таким образом, в таблице public.user будут храниться логин и пароль, а так же пользовательские настройки, общие для автомойки и шиномонтажа. А в таблицах carwash.user (автомойка) и tireservice.user (шиномонтажа) будут храниться настройки пользователей, характерные для каждой программы. Например, доступ к какому-нибудь отчету.

Процесс аутентификации

Как происходит аутентификация и авторизация в WT-программе

1. Форма входа

Когда пользователь запускает программу, открывается форма входа в программу:

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

2. Запрос на список пользователей

Когда открывается форма аутентификации, на сервер отправляется запрос на получение списка пользователей. Все запросы к серверу подписываются учеткой текущего пользователя программы. Так как вход в программу еще не осуществлен, то запрос на список активных пользователей подписывается гостевой учеткой WS_GUEST, логин и пароль которой указаны в конфиге клиентской части (WorkflowForms.dll.config).

Список пользователей формируется с помощью SQL-запроса вида:

Template.xml
<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.

В PostgreSQL представление (VIEW) - это виртуальная таблица, созданная запросом joins, соединяющим одну или несколько таблиц.

Про представления в PostgreSQL можно почитать в официальном документации по ссылке.

3. Команда входа

На форме входа пользователь выбирает в выпадающем списке свою учетку и вводит пароль. По кнопке "Войти", клиентская часть хеширует введенный пароль безопасным алгоритмом SHA-512 и отправляет на сервер запрос с логином и хешом пароля в зашифрованном виде, используя для этого команду типа LoginCommand .

4. Аутентификация на сервере

Когда запрос приходит на сервер, он попадает сначала в веб-сервер Kestrel, на котором запущена веб-служба, а затем перенаправляется в серверное приложение.

Kestrel представляет кроссплатформенный веб-сервер и по умолчанию включается в проект ASP.NET Core.

На сервере механизм аутентификации и авторизации реализован с помощью JWT-токенов. Когда Workflow Engine получает запрос на аутентификацию пользователя, полученные логин и хеш пароля сверяются с теми, которые хранятся в таблице public.user в базе данных. Если логин и хеш пароля совпали - генерируется JWT-токен, который возвращается клиентскому приложению вместе с временем жизни этого токена и одноразовым токеном для повторной генерации основного JWT-токена.

JWT (или JSON Web Token) представляет собой веб-стандарт, который определяет способ передачи данных о пользователе в формате JSON в зашифрованном виде.

5. Использование токенов

Клиентское приложение хранит JWT-токен и подписывает им все последующие запросы к серверу. Так же клиентская часть сама отслеживает время жизни JWT-токена: если JWT-токен устарел, то отправит запрос на обновление основного JWT-токена.

6. Авторизация на сервере при запросе

Сервер, получив запрос от клиентской части, проверяет JWT-токен, которым подписан запрос. Если токен актуален, то авторизация считается успешной, и происходит проверка Прав доступа у пользователя на выполнение запроса или команды.

Last updated