Интеграция с SSO Keycloak

Интеграцию с SSO (Single Sign-On — технология единого входа) Keycloak (на базе Open ID) можно использовать, если нет возможности подключить интеграцию с Active Directory.

Интеграция с SSO позволяет:

  • Выполнять защищенный вход в приложение через единую учетную запись.
  • Создавать и изменять пользователей.
  • Назначать роли пользователям.
  • Просматривать список пользователей, которые находятся онлайн на инстансе в данный момент (аналогично просмотру пользователей со статусом В сети). Список активных пользователей вы можете просмотреть только на данный момент, без возможности просмотра данных в прошлом.

Подключить интеграцию вы можете в файле конфигурации с помощью специальной настройки:

  • Если настройка включена, все пользователи при входе или выходе из Case.one будут перенаправлены на страницу аутентификации Keycloak.
  • Если настройка выключена, используется аутентификация согласно настройкам приложения.

При включенной интеграции с SSO Keycloak в Case.one недоступно:

  • Создание пользователей.
  • Редактирование сведений о пользователе в Case.one, которые указаны в обязательных полях и синхронизируются с SSO Keycloak.
  • Изменение ролей пользователей.
  • Изменение групп у пользователей.

Авторизация через SSO

При передаче данных SSO Keycloack в Case.one поиск пользователя в Case.one выполняется по значению параметра email.


Благодаря проверке по адресу электронной почты не возникнет ошибка авторизации, связанная с повторным созданием ранее созданного пользователя в SSO Keycloak на другом сервере SSO Keycloak.


При попытке авторизации пользователя с уже зарегистрированным адресом электронной почты:

  • Если внешний идентификатор не совпадает:
    • Выполнится связь пользователя в Case.one с данными из SSO Keycloack
    • Пользователь будет авторизован
  • Если идентификатор отсутствует, авторизация будет выполнена.


Вид и функциональность страницы аутентификации реализован на стороне Keycloak.


При авторизации пользователя через SSO Keycloak, если авторизация прошла успешно, на стороне Case.one выполняются проверки:

  • Статуса пользователя — заблокированный пользователь не сможет авторизоваться.
  • Наличия активных лицензий — если активная подписка найдена, пользователь успешно авторизовывается в Case.one.
  • Проверка IP-адреса пользователя:
  • Проверка наличия ограничений по количеству пользователей в системе согласно тарифному плану.
  • Проверка наличия запрета авторизации на инстансе Case.one пользователям с определенными ролями.

Если хоть одна проверка не пройдена:

  • Выполняется разрыв активной сессии авторизации пользователя в SSO (Keykloack).
  • Пользователь будет перенаправлен на страницу с описанием ошибки:
    • Если пользователь заблокирован в Case.oneПользователь заблокирован, обратитесь к администратору. Для возврата на форму авторизации обновите страницу
    • Если отсутствует активная лицензия — Не найдено ни одной активной лицензии, обратитесь к администратору. Для возврата на форму авторизации обновите страницу
    • Если IP-адрес пользователя не соответствует разрешенному диапазону IP-адресов — Вы пытаетесь зайти в систему с недопустимым IP-адресом, пожалуйста, обратитесь к администратору. Для возврата на форму авторизации обновите страницу
    • При достижении лимита по количеству пользователей согласно текущему тарифу — На вашем аккаунте достигнуто ограничение по количеству пользователей. Улучшите вашу подписку для увеличения количества пользователей в сервисе. Для возврата на форму авторизации обновите страницу 
    • При наличии запрета на авторизацию для роли, которой обладает пользователь, попытавшийся авторизоваться — Доступ запрещен, пожалуйста, обратитесь к администратору. Для возврата на форму авторизации обновите страницу 

Создание пользователя

Через SSO будет создана новая карточка пользователя:

  • При новой попытке авторизоваться, если пользователь был удален на стороне Case.one.
  • Если в Case.one нет аутентифицированного пользователя.

При передаче данных SSO Keycloack предоставляет уникальный идентификатор пользователя в Keycloack, при создании пользователя в Case.one этот идентификатор сохраняется.

По уникальному идентификатору пользователя можно определить, является ли пользователь новым или уже существует в Case.one


В карточку пользователя будет внесена следующая информация, полученная от SSO:

  • Фамилия
  • Имя
  • Отчество
  • Инициалы — добавляются в Case.one на основании ФИО
  • Email
  • Внешний идентификатор
  • Должность и Организация — при отсутствии сведений поля будут пустыми

Если пользователь уже существует Case.one, его роли и информация по нему автоматически обновляются при получении данных из SSO.


При включенной интеграции с SSO Keycloack данные о пользователе будут автоматически обновляться, например:

  • При изменении значения поля Отчество в SSO Keycloack значение будет автоматически обновлено в Case.one при следующем обмене данными.
  • Если поле Отчество не заполнено в SSO Keycloack, значение поля в Case.one будет сброшено при следующем обмене данными.
  • В конфигурационном файле возможно указать соответствия поля Отчество.

При включенной интеграции также доступно назначение ролей пользователям на основе сведений, полученных через SSO Keycloak:

  • Если сведения о роли получены, при наличии в Case.one соответствия пользователю будет назначена указанная роль.
  • При наличии нескольких совпадений ролей в Case.one пользователю будет назначена первая роль из списка совпавших.
  • Если роль не найдена или не указана, в Case.one будет автоматически создана новая роль:
    • Название роли в Case.one будет получено из SSO Keycloack
    • В роли будут назначены права Просмотр на раздел Личный кабинет → Профиль (на остальные разделы права не будут присвоены) 
  • Если интеграция включена, в Case.one недоступно создавать, удалять роли или изменять название.
  • При назначении или изменении роли через SSO Keycloack в разделе Действия в системе в Case.one будут добавлен следующие события от имени системы (Workflow Service):
    • Редактирование данных пользователя
    • Создание роли
    • Изменение прав созданной роли на Просмотр в разделе Личный кабинет → Профиль

Настройки интеграции в файле конфигурации

Для включения интеграции с OpenId добавьте настройку EnableOpenIdIntegration="True" в файл настроек конфигурации appsettings.json.


При включенной интеграции с OpenId должны быть отключены интеграция с Active Directory и Windows-аутентификация.


В файле appsettings.json доступна секция OpenId со следующими параметрами:

{
    "Custom": {
        // ... other settings
        "EnableOpenIdIntegration": "true"
    },
    "OpenId":
    {
        "ClaimsIssuer": "http[s]://opentid-provider-host",
        "ClientId": "caseone",
        "ClientSecret": "zFkncy1iV7giJUaMPAJJP0CgX4vqdCFr",
        "AuthorizationEndpoint": "http[s]://opentid-provider-host/path/to/auth/endpont",
        "TokenEndpoint": "http[s]://opentid-provider-host/path/to/token/endpont",
        "EndSessionEndpoint": "http[s]://opentid-provider-host/path/to/end/session/endpont",
        "Scopes": "openid, profile, email", 
// The scopes are the scopes of the JWT token. 
Default is "openid, profile, email".
        "UserInfoPaths": {
            // You can specify a path as a value, 
for example "realm_access.roles": select the roles located in
            // "realm_access": {
            //     "roles": [ "role1", "roles2" ]
            // }
            "UserId": "sub", 
// The user id is the subject of the JWT token. Default is "sub".
            "FirstName": "given_name", 
// The first name is the given name of the JWT token. Default is "given_name".
            "LastName": "family_name", 
// The last name is the family name of the JWT token. 
Default is "family_name".
            "MiddleName": "ваш_путь_к_отчеству"

 "Email": "email", // The email is the email of the JWT token. 
Default is "email".

            "Company": "company", 
// The company is the company of the JWT token. Default is "company".
            "Title": "title", 
// The title is the title of the JWT token. Default is "title".
            "Roles": "roles" 
// The roles are the roles of the JWT token. Default is "roles
        },
        "RoleMaps": [
            {
                "Source": "admin", // role in OpenID provider
                "Destination": "Администратор" // role in the CaseOne
            }
        ],
        "RefreshTokenReuseTimeout": "00:00:30", 
// The refresh token reuse timeout is the time to reuse the refresh token.
 Default is "00:00:30".
        "RefreshTokenRequestTimeout": "00:00:10", 
// The refresh token request timeout is the time to request the refresh token.
 Default is "00:00:10".
        "TokenCleanerPollingInterval": "00:01:00", 
// The token cleaner polling interval is the time to clean the token. 
Default is "00:01:00".
        "LogoutRequestTimeout": "00:00:10" 
// The logout request timeout is the time to request the logout. D
efault is "00:00:10".
    }
}

Если провайдер идентификации использует другое название утверждения для отчеств, а не стандартное  утверждение (claim) в OpenID Connect, вы можете настроить в параметрах приложения.

Если поле отчества не предоставляется провайдером идентификации или не настроено, система будет продолжать функционировать как раньше, а поле отчества останется пустым.


Аутентификация в публичном и приватном API

Для аутентификации в публичном и приватном API с помощью токена, полученного в SSO Keycloak (OpenID), в файле настроек конфигурации appsettings.json доступны параметры конфигурации SSO  для валидации и обработки токенов OpenID/SSO Keycloak:

  • Для поддержки валидации токенов доступны следующие параметры в секцию OpenId:
    • Audience (string) — валидация параметра aud в JWT-токене, полученном от OpenId провайдера:
      • Если не заполнено, в качестве значения берется параметр OpenId::ClientId
      • Значение по умолчанию — null
    • ClaimsIssuer (string) — URL провайдера OpenID:
      • Значение по умолчанию — true
      • Параметр обязателен, если ValidateIssuer = true
    • ValidateIssuer (boolean) — проверка издателя токена (значение по умолчанию — true)
    • ValidateAudience (boolean) — проверка получателя токена (значение по умолчанию — true)
    • ValidateLifetime (boolean) — проверка времени жизни токена (значение по умолчанию — true)
    • ValidateIssuerSigningKey (boolean) — проверка подписи токена (значение по умолчанию — true)
    • UpdateOpenIdUserInterval (TimeSpan) — интервал обновления данных пользователя (значение по умолчанию — 00:10:00)
Пример конфигурации:
{
    "OpenId": {
        "ValidateIssuer": true,
        "ValidateAudience": true,
        "ValidateLifetime": true,
        "ValidateIssuerSigningKey": true,
        "UpdateOpenIdUserInterval": "00:15:00"
    }
}
  • Настройки параметров в Keycloak:
    • Audience:
      • Значение: account
      • Соответствует параметру aud в JWT-токене
    • ValidateIssuer:
    • ValidateAudience:
      • Настраивается: Clients → Your Client → Settings → "Client ID"
      • Дополнительные настройки: Valid Redirect URIs и Web Origins
      • Должен совпадать с параметром Audience
    • ValidateLifetime — настройки времени жизни токена:
      • Realm Settings → Tokens:
        • Access Token Lifespan
        • Client Session Idle
        • Client Session Max
      • Clients → Your Client → Settings:
        • Access Token Lifespan
        • Client Session Idle
        • Client Session Max
    • ValidateIssuerSigningKey:
      • Управление: Realm Settings → Keys
      • Поддерживает ротацию ключей
      • Endpoints для получения публичного ключа:
        • /.well-known/openid-configuration
        • /protocol/openid-connect/certs

Механизм работы с пользователями:

  • Процесс авторизации
    • Если пользователь отсутствует, будет создан новый пользователь с привязкой к внешнему ID
    • Если пользователь существует без внешнего ID, пользователь будет привязан к внешнему ID из запроса
    • Если пользователь существует с другим внешним ID, возвращается ошибка
  • Обновление данных пользователя:
    • Периодичность — согласно UpdateOpenIdUserInterval
    • Триггер — при запросе с токеном
    • Обновляемые данные — базовая информация из токена

Проверка подписи токена

Доступна дополнительная проверка подписи токена с помощью набора открытых ключей JWKS. Для поддержки валидации JWKS добавлены следующие параметры конфигурации в секции OpenId:

  • EnableJWKSValidation (boolean) — включение/отключение валидации подписи токена согласно JWKS (значение по умолчанию — false).
  • JWKSUrlEndpoint (string) — URL точки доступа для получения набора открытых ключей JWKS (значение по умолчанию — null).

Проверка токена согласно JWKS работает только при включенной интеграции с OpenId.


Поставщик ключей JWKS может находиться на любом удаленном сервере или предоставляться через SSO-провайдер. Для Keyclock получить JWKSUrlEndpoint можно из конфигурации OpenID: http://keycloack_base_url/auth/realms/your_realm/.well-known/openid-configuration (параметр jwks_uri).

Пример: http://keycloack_base_url/auth/realms/your_realm/protocol/openid-connect/certs

Пример конфигурации с включенной валидацией согласно JWKS:

Custom: {
      "EnableOpenIdIntegration": "true" 
// Интеграция с OpenID должна быть включена
    }
    "OpenId": {
        "ClaimsIssuer": "http://openid-provider-host/auth/realms/your_realm", 
// URL провайдера OpenID
        "ClientId": "some_id",
// идентификатор клиента на стороне провайдера OpenID
        "ClientSecret": "xxx-xxx-xxx-xxxx-xxxxxx", 
// секрет клиента для доступа к API провайдера OpenID
        "EnableJWKSValidation": true, 
// Включение валидации подписи токена согласно 
полученному набору открытых ключей JWKS. 
Параметр JWKSUrlEndpoint должен быть обязательно 
заполнен при активации данной настройки
        "JWKSUrlEndpoint": "http[s]://openid-provider-host/auth/realms/your_realm/protocol/openid-connect/certs", 
// URL точки доступа для получения набора открытых ключей JWKS
        "AuthorizationEndpoint": "http[s]://openid-provider-host/auth/realms/your_realm/protocol/openid-connect/auth", 
// URL точки доступа для аутентификации пользователей
        "TokenEndpoint": "http[s]://openid-provider-host/auth/realms/your_realm/protocol/openid-connect/token", 
// URL точки доступа для получения и обновления токена доступа
        "EndSessionEndpoint": "http[s]://openid-provider-host/auth/realms/your_realm/protocol/openid-connect/logout" 
// URL точки доступа для завершения сессии пользователя
    }

При любой ошибке валидации подписи токена через JWKS сеанс текущего пользователя прекращается.


Online-валидация токена

С помощью Keycloak доступна online-валидация токена. Механизм online-валидации является опциональным и по умолчанию выключен.

Для включения механизма online-валидации:

  1. В админке Keycloak перейдите на вкладку Realm settings.
  2. В конце страницы, в разделе Endpoints откройте OpenID Endpoint Configuration, скопировав значение свойства introspection_endpoint.
  3. Добавьте скопированное значение в appsettings.json → OpenId → IntrospectEndpoint.
  4. Добавьте в appsettings.json → OpenId свойство "UseOnlineTokenVerification": true.
"OpenId": {
    "IntrospectEndpoint": "https://keycloak.linux.test.case.int/realms/local-dev/protocol/openid-connect/token/introspect", 
// url точки доступа для валидации токена
    "UseOnlineTokenVerification":  true 
// флаг, указывающий на необходимость валидации токена
}

Настройка времени жизни сессии

Возможно настроить время жизни сессии, чтобы исключить ситуации, когда сессия Case.one уже завершена, а сессия SSO Keycloak еще действует.

Чтобы задать время жизни сессии, установите следующие значения параметров SSO Keycloak в разделе Clients → Advanced → Advanced settings:

Client Session Idle == Inherits from realm settings
Client Session Max == Inherits from realm settings
Access Token Lifespan < Client Session Idle