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

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

В этот статье рассматривается процесс аутентификации, а правам доступа посвящена одноименная [стать](/wt-knowledge-base/platform-wt/access-rights.md).

{% hint style="info" %}
Аутентификация - процедура проверки подлинности, например проверка подлинности пользователя путем сравнения введенного им пароля с паролем, сохраненным в базе данных.

Авторизация - предоставление определенному лицу или группе лиц прав на выполнение определенных действий.
{% endhint %}

## Список пользователей <a href="#users-list" id="users-list"></a>

Для начала рассмотрим, как представлен список пользователей в базе данных.

В базе данных в таблице **public.user** хранится общий список пользователей системы:

<figure><img src="/files/Mc2xJYBFCAYexGPSaaw7" alt=""><figcaption></figcaption></figure>

Описание полей таблицы:

* 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:

<figure><img src="/files/uGKM648lGNNXhCGjFs0l" alt=""><figcaption></figcaption></figure>

Так же в эту таблицу можно добавить поля для индивидуальных пользовательских настроек, например, для доступа к какому-нибудь отчету.

{% hint style="info" %}
WT-приложение может объединять несколько программ для разных бизнес-процессов, например, для автомойки и шиномонтажа.

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

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

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

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

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

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

<figure><img src="/files/mHkHgmnPPO4esXvPCBwh" alt=""><figcaption></figcaption></figure>

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

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

Когда открывается форма аутентификации, на сервер отправляется запрос на получение списка пользователей. Все запросы к серверу подписываются учеткой текущего пользователя программы. Так как вход в программу еще не осуществлен, то запрос на список активных пользователей подписывается гостевой учеткой WS\_GUEST, [логин](https://wfsys.gitbook.io/wt-knowledge-base/platforma-wt/configuration-files/workflowforms.dll.config#anonymous_user_name) и [пароль](https://wfsys.gitbook.io/wt-knowledge-base/platforma-wt/configuration-files/workflowforms.dll.config#anonymous_password) которой указаны в конфиге клиентской части ([WorkflowForms.dll.config](https://wfsys.gitbook.io/wt-knowledge-base/platforma-wt/configuration-files/workflowforms.dll.config)).&#x20;

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

{% code title="Template.xml" %}

```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>
```

{% endcode %}

В запросе используется **template.user\_info** - это представление, которое динамически строится на основе двух таблиц: **template.user** и **public.user**.

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

Про представления в PostgreSQL можно почитать в официальном документации по [ссылке](https://postgrespro.ru/docs/postgrespro/15/sql-createview).
{% endhint %}

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

На форме входа пользователь выбирает в выпадающем списке свою учетку и вводит пароль. По кнопке "Войти", клиентская часть хеширует введенный пароль безопасным алгоритмом *SHA-512* и отправляет на сервер запрос с логином и хешом пароля в зашифрованном виде, используя для этого  команду типа [LoginCommand](https://wfsys.gitbook.io/workflow-forms-syntax/workflow_forms/commands/login_command) .

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

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

{% hint style="info" %}
Kestrel представляет кроссплатформенный веб-сервер и по умолчанию включается в проект ASP.NET Core.
{% endhint %}

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

{% hint style="info" %}
JWT (или JSON Web Token) представляет собой веб-стандарт, который определяет способ передачи данных о пользователе в формате JSON в зашифрованном виде.
{% endhint %}

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

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

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

Сервер, получив запрос от клиентской части, проверяет JWT-токен, которым подписан запрос. Если токен актуален, то авторизация считается успешной, и происходит проверка [Прав доступа](/wt-knowledge-base/platform-wt/access-rights.md) у пользователя на выполнение запроса или команды.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://wfsys.gitbook.io/wt-knowledge-base/platform-wt/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
