.. _spec_server_authentication: Аутентификация пользователей ============================= Введение ---------------------- Аутентификация — это процесс проверки подлинности пользователя или объекта, который пытается получить доступ к системе или ресурсу. Аутентификация подтверждает, что пользователь является тем, за кого себя выдает, и предоставляет доступ на основе предъявленных учетных данных. После успешной аутентификации, сервер формирует :ref:`spec_server_authentication_token`, который возвращается клиенту в Cookie :ref:`access_token`. HTTP-запрос, содержащий Cookie ``access_token`` c валидным токеном, считается аутентифицированным. Для различных :ref:`точек доступа` системы Global доступны разные типы аутентификации. **Frontend приложений Global** - :ref:`Form` - :ref:`OpenID` - :ref:`Proxy` **Backend приложений Global и HTTP сервисы** - :ref:`Basic` - :ref:`Bearer` - :ref:`Proxy` .. _spec_server_authentication_token: Аутентификационный токен ---------------------------- Аутентификационный токен – это, по сути, цифровой "билет", который подтверждает личность пользователя при доступе к системе. Он выдается системой после успешной аутентификации и позволяет избежать повторного ввода логина и пароля при каждом обращении. Токен аутентификации является строкой в формате: ``{тип}_{тело}``. Где: - ``{тип}`` — Тип токена. - ``{тело}`` — Тело токена: :term:`хэш` или :term:`JWT`. Типы токенов ~~~~~~~~~~~~~~~~ Тип токена определяет место валидации и алгоритм обработки содержимого токена. .. note:: За сервером приложений зарезервированы имена типов, начинающиеся с символа ``a``. В текущей версии, сервер приложений формирует токены с типами: .. _spec_server_authentication_token_ast: - ``ast`` — Application Server Token ``Ast``-токен формируется сервером приложений после входа пользователя в систему Global — с использованием имени пользователя и пароля либо посредством аутентификации во внешнем сервисе идентификации. Токен возвращается клиенту в Cookie('access_token'), привязанной к подмножеству адресов ``http[s]://{global.server}/{DATABASE}/``. Эта Cookie автоматически присоединяется ко всем запросам по адресам ``http[s]://{global.server}/{DATABASE}/``, выполняемым из браузера, аутентифицированного в системе Global. ``Дата истечения срока действия`` — дата, после которой токен перестаёт быть валидным. ``Интервал обновления`` — временной интервал перед наступлением даты истечения срока действия, в течении которого будет создан и передан клиенту новый токен. При обработке HTTP-запроса сервер проверяет, попадает ли текущая дата в этот интервал. Если попадает, сервер возвращает клиенту Cookie("access_token") с новым токеном. .. note:: Вычисляется по формуле: ``Math.min(15, Math.max(60 * 60, astTokenLifeTime / 4))`` Где ``astTokenLifeTime`` — время жизни ``ast``-токена. Сервер приложений периодически (по таймеру, с интервалом в половину интервала обновления) проверяет наступление интервала обновления ``ast``-токенов для всех подключенных клиентов. При установлении факта скорого наступления даты истечения срока действия, клиенту направляется сообщение о необходимости выполнения HTTP-запроса к серверу для получения нового токена. .. note:: Если не указан :xsd:attr:`idleClientTimeout `, время жизни ``ast``-токена — 48 часов. Если указан ``idleClientTimeout``, время жизни ``Ast``-токена равно ``idleClientTimeout``. Это необходимо, что бы после закрытия окна браузера и повторном входе в систему, через промежуток времени больший ``idleClientTimeout``, система потребовала повторной аутентификации. Валидация токенов других типов выполняется в :term:`GTK`, вызовом :java:meth:`CoreAuthProvider.loginBearer()`. Типы аутентификации ---------------------- .. _spec_server_authentication_form: Form ~~~~~~~~~~~~~~~~~~ Аутентификация выполняется сервером Global на основе учётных данных, переданных через форму входа в систему Global. - При обращении к серверу Global, не аутентифицированный браузер пользователя направляется на страницу входа. - Пользователь вводит свои имя и пароль в поля формы входа в систему Global . - По нажатию кнопки "Вход" учётные данные передаются на сервер Global через тело HTTP POST запроса. - Сервер выполняет проверку учётных данных в соответствии с :xsd:class:`настройками для базы данных` в конфигурации сервера. - В случае успешного завершения проверки учётных данных и перенаправляет браузер на запрашиваемый ресурс. Адрес формы входа: ``http[s]://{global.server}/login/login.html``. .. code-block:: xml :caption: global3.config.xml
Аутентификация через форму входа является умолчательным способом аутентификации и не требует явного включения в конфигурации сервера. Секция ```` может отсутствовать. .. note:: Если в конфигурации указаны OpenId-провайдеры, аутентификация через форму входа по умолчанию отключается. При этом сама форма входа, без полей ввода логина и пароля, остаётся доступной. Нажатие кнопки "Вход" направляет браузер на адрес провайдера идентификации по умолчанию. .. seealso:: :xsd:class:`Configuration.Security.Authenticators.Form` .. _spec_server_authentication_openid: OpenID ~~~~~~~~~~~~~~~~~~ Аутентификация выполняется в стороннем сервисе, провайдере идентификации, взаимодействие с которым производится по протоколу `OpenID Connect `__. Примеры провайдеров идентификации: Azure Active Directory, Keycloak, Avanpost FAM. - При обращении к серверу Global, сервер формирует сеансовый ключ и направляет браузер пользователя на страницу провайдера идентификации. - Пользователь сообщает свои учётные данные провайдеру идентификации (имя и пароль, цифровой ключ и т.д, в зависимости от провайдера). - В случае успешного завершения проверки учётных данных, провайдер идентификации направляет браузер пользователя обратно, на сервер Global. - Сервер Global, по сеансовому ключу, запрашивает у провайдера идентификации данные пользователя и токены доступа. - В случае успешного получения данных пользователя от провайдера идентификации, сервер Global вызывает метод :java:meth:`CoreAuthProvider.loginOpenId()`, для сопоставления имени пользователя провайдера идентификации с пользователем системы Global, и перенаправляет браузер на запрашиваемый ресурс. .. code-block:: xml :caption: global3.config.xml для Keycloak Где: - ``{provider_name}`` — уникальное, в контексте конфигурации, имя провайдера идентификации. Это имя будет использоваться при формировании url-адреса провайдера на сервере Global. - ``{provider_address}`` — url-адрес провайдера идентификации. Пример: ``https://auth.g-sys.ru/realms/dev-test``. - ``{client_id}`` — идентификатор клиента (Сервера Global) в провайдере идентификации. Уникальный идентификатор, который получает клиентское приложение при регистрации у поставщика удостоверений (OpenID провайдера). Он используется для идентификации приложения при запросе аутентификации у пользователя и позволяет провайдеру знать, какое приложение запрашивает доступ. - ``{client_secret}`` — секрет клиента (Сервера Global) в провайдере идентификации. Пароль, который используется клиентским приложением (Сервером Global) для аутентификации при взаимодействии с OpenID провайдером. Он служит для подтверждения подлинности приложения, которое запрашивает токены для пользователя. .. note:: В конфигурации может быть указано несколько провайдеров идентификации OpenID Connect. В этом случае, провайдером по умолчанию будет являться первый или тот, у которого установлен атрибут ````. | Вместо атрибута ``secret="{client_secret}"`` может быть использован ``encryptedSecret="{encrypted_client_secret}"``. | Где ``{encrypted_client_secret}``, это - ``{client_secret}`` зашифрованный :xsd:elem:`мастер паролем`. Для каждого OIDC провайдера, указанного в конфигурации, сервер Global запускает точку доступа, через которую происходит взаимодействие с провайдером. Адрес провайдера идентификации на сервере Global: ``http[s]://{global.server}/login/openid/{name}``. Где: - ``{global.server}`` — адрес сервера Global. - ``{name}`` — это значение атрибута ```` или имя домена из адреса сервера в атрибуте ````, если ``name`` не указано. .. note:: Если в конфигурации указано несколько провайдеров идентификации, для обращения к конкретному провайдеру требуется направить браузер по адресу этого провайдера. При запуске сервера Global, в конфигурации которого определен(ы) OpenId провайдер(ы) идентификации, выполняется http-запрос к провайдеру(ам) под адресу ``{PROVIDER_ADDRESS}/.well-known/openid-configuration`` для получения адресов точек доступа и списка публичных RSA-ключей, используемых при проверке токенов. Автоматический вход `````````````````````` Вход пользователя в систему без отображения диалога входа в Global. При получении сервером Global не аутентифицированного запроса на корневой адрес ``http[s]://{global.server}/``, логика работы зависит от свойства :xsd:attr:`Configuration.Security.Authenticators.OpenId.autoLogin`. - ``true`` — выполнится перенаправление браузера на провайдер идентификации по умолчанию. - ``false`` — выполнится перенаправление браузера форму входа в систему Global ``http[s]://{global.server}/login/login.html``. .. seealso:: :xsd:class:`Configuration.Security.Authenticators.OpenId` Code Flow with PKCE ```````````````````````````````````````` Для дополнительной защиты процедуры обмена авторизационными кодами между сервером Global, браузером и провайдером идентификации используется расширение PKCE (Proof Key for Code Exchange) протокола OAuth 2.0. При формировании URL авторизационного запроса сервер Global добавляет параметры: .. code-block:: code_challenge={codeChallenge} code_challenge_method=S256 Где: - ``{codeChallenge}`` - Base64 строка SHA256-хэша от {codeVerifier}. При последующем обращении сервера Global к провайдеру идентификации для обмена авторизационного кода на токен в теле POST-запроса добавляется параметр: .. code-block:: code_verifier={codeVerifier} Где: - ``{codeVerifier}`` - случайная строка длиной от 43 до 128 символов. Такой механизм предотвращает использование перехваченного авторизационного кода злоумышленником и обеспечивает привязку авторизационного запроса к конкретному клиенту. .. seealso:: `Authorization Code Flow with Proof Key for Code Exchange (PKCE) `__ Back-Channel Logout `````````````````````` Для обеспечения работы механизма централизованного выхода из системы, для каждой конфигурации провайдера идентификации сервер Global создаёт точку доступа с адресом: ``http[s]://{global.server}/login/openid/{name}/backchannel-logout``. Этот адрес указывается в настройках провайдера идентификации (Не в конфигурации сервера Global, а в настройках сервера Azure Active Directory, Keycloak, Avanpost FAM и др.). - При завершении сеанса пользователя в провайдере идентификации, провайдер идентификации отправляет POST-запрос, содержащий в теле `logout_token={JWT}`, по адресу сервера Global, указанному в настройках провайдера. - Сервер Global выполняет валидацию полученного токена выхода, используя публичный RSA-ключ, полученный от провайдера идентификации при запуске сервера Global. - Если подпись токена соответствует публичному ключу провайдера идентификации, сервер Global завершает все рабочие сеансы пользователя, связанные с завершённым сеансом в провайдере идентификации. .. note:: Пользователь может быть авторизован в провайдере идентификации с нескольких устройств (браузеров). Это будет соответствовать нескольким сеансам в провайдере идентификации. Завершение сеанса на одном устройстве не завершает сеансов для остальных устройствах. .. seealso:: `OpenID Connect Back-Channel Logout 1.0 `__ .. _spec_server_authentication_proxy: Proxy ~~~~~~~~~~~~~~~~~~ Аутентификация пользователя с помощью прокси-сервера, через который проходят все запросы к серверу Global. - При обращении к серверу Global, запрос проходит через прокси-сервер, где выполняется аутентификация средствами прокси или внешнего провайдера идентификации. - После успешной аутентификации, прокси добавляет к HTTP-запросу заголовки: - ``X-Remote-User`` — имя пользователя. - ``X-Proxy-Token`` — аутентификационный токен прокси-сервера. - Прокси направляет запрос к сервер приложений Global, по адресу содержащему имя решения ``http[s]://server.domain/{SOLUTION}/``. - Сервер Global проверяет заголовки и вызывает метод :java:meth:`CoreAuthProvider.loginRemote()` для проверки токена прокси-сервера и получения списка привилегий пользователя. - Если токен прокси-сервера валиден, пользователь считается аутентифицированным. Сервер Global разрешает доступ к запрашиваемому ресурсу. .. code-block:: xml :caption: global3.config.xml .. seealso:: :xsd:class:`Configuration.Security.Authenticators.Proxy` .. _spec_server_authentication_basic: Basic ~~~~~~~~~~~~~~~~~~ Аутентификация выполняется сервером Global на основе учётных данных переданных через http-заголовок ``Authorization``. Клиент должен передать в запросе: - Имя пользователя - Пароль - Имя базы Имя пользователя и пароль передаются через HTTP-заголовок: - ``Authorization`` со значенеим ``Basic {Base64Cred}`` где: ``{Base64Cred}`` — строка ``user:password``, кодированная в `Base64`. Имя базы может быть передано через (в порядке приоритета): - Сегмент строки адреса. Пример: ``http://server/{DATABASE}/`` - HTTP-заголовок ``Database`` со значением ``{DATABASE}`` - HTTP-параметр ``Database`` со значением ``{DATABASE}``. Пример: ``http://server/?Database={DATABASE}`` где ``{DATABASE}`` — имя базы данных. .. note:: Если имя базы не передано ни одним из описанных способов, будет произведена попытка аутентификации с использованием имени базы по-умолчанию. База по умолчанию определяется из конфигурационного файла `global3.config.xml` (в порядке приоритета). - Значение атрибута ```` - Значение атрибута ```` первой базы в списке конфигураций ```` Проверка учётных данных для Postgres решения выполняется в :term:`GTK`, вызовом :java:type:`CoreAuthProvider.login()`. .. _spec_server_authentication_bearer: Bearer ~~~~~~~~~~~~~~~~~~ Аутентификация выполняется сервером Global на основе токена, переданного через http-заголовок ``Authorization``. Клиент должен передать в запросе: - :term:`Токен аутентификации` - Имя базы Токен аутентификации передаётся через HTTP-заголовок: - ``Authorization`` со значением ``Bearer {Token}`` где: ``{Token}`` — строка с токеном аутентификации. .. note:: Токен может быть передан одним из способами: - Через cookie с именем ``access_token`` - Через параметр с именем ``access_token`` Имя базы может быть передано через (в порядке приоритета): - Сегмент строки адреса. Пример: ``http://server/{DATABASE}/`` - HTTP-заголовок ``Database`` со значением ``{DATABASE}`` - HTTP-параметр ``Database`` со значением ``{DATABASE}``. Пример: ``http://server/?Database={DATABASE}`` где ``{DATABASE}`` — имя базы данных. .. note:: Если имя базы не передано ни одним из описанных способов, будет произведена попытка аутентификации с использованием имени базы по-умолчанию. База по умолчанию определяется из конфигурационного файла `global3.config.xml` (в порядке приоритета). - Значение атрибута ```` - Значение атрибута ```` первой базы в списке конфигураций ```` Проверка токена для Postgres решения выполняется в :term:`GTK`, вызовом :java:type:`CoreAuthProvider.loginBearer()`. Конфигурирование ---------------------- Определение перечня доступных способов аутентификации, для входа в приложения Global, производится в конфигурационном файле сервера :ref:`global3.config.xml`, в разделе :xsd:class:`Configuration.Security.Authenticators`. .. code-block:: xml :caption: global3.config.xml