Конфигурация SSO c Keycloak
Перед настройкой SSO убедитесь, что в config.env параметр APP_URL соответствует текущему домену Пассворка, пример — APP_URL=https://passwork.example.com
Это нужно, чтобы IDP смог скачать metadata. Также сервер Пассворка должен работать по HTTPS протоколу.
Для примера используются следующие имена серверов:
- Провайдер (IDP) — keycloack.passwork.local
- Сервер Пассворка (SP) — passwork.example.com
Создание приложения с помощью импорта файла в Keycloack
Получить и отредактировать файл для создания приложения с стороны IDP.
Скачать keycloack.json
Содержимое keycloack.json
{
"clientId": "https://passwork.example.com/api/v1/sso/metadata",
"rootUrl": "",
"adminUrl": "https://passwork.example.com/api/v1/sso/acs",
"baseUrl": "https://passwork.example.com/*",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"https://passwork.example.com/*"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"frontchannelLogout": true,
"protocol": "saml",
"attributes": {
"saml.force.post.binding": "true",
"saml.multivalued.roles": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature.keyinfo.ext": "false",
"use.refresh.tokens": "true",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.session.required": "false",
"saml.signature.algorithm": "RSA_SHA256",
"client_credentials.use_refresh_token": "false",
"saml.client.signature": "false",
"saml.assertion.signature": "false",
"saml.encrypt": "false",
"saml.server.signature": "true",
"exclude.session.state.from.auth.response": "false",
"saml.artifact.binding": "false",
"saml_force_name_id_format": "true",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "true",
"display.on.consent.screen": "false",
"saml_name_id.format": "email",
"saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#",
"saml.onetimeuse.condition": "false",
"saml.logout.url": "https://passwork.example.com/api/v1/sso/sls"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"role_list"
],
"optionalClientScopes": [],
"access": {
"view": true,
"configure": true,
"manage": true
}
}
- json
"clientId": "https://your_host/api/v1/sso/metadata",
"adminUrl": "https://your_host/api/v1/sso/acs",
"baseUrl": "https://your_host/*",
"saml.logout.url": "https://your_host/api/v1/sso/sls"
Открыть веб-интерфейс Keycloack и перейти в — Clients → Import client:

Выполнить следующие действия:
- Импортировать изменённый файл приложения;
- Задать имя создаваемого приложения;
- Отключить — Encrypt assertions;
- Отключить — Client signature required.
Сохранить внесённые изменения:

При необходимости можно изменить уникальный идентификатор пользователя (NameID) внутри SAML-assertion после сохранения предыдущих действий:

Рекомендуем указывать username или email, в зависимости от выбранного значения логин пользователя в Пассворке может иметь следующие форматы:
- username
- username@passwork.local
Настройка передачи ролей пользователя в SAML-assertion
Перейти и создать общий набор настроек для приложения (SP) — Client scopes → Create client scope:

Выполнить следующие действия:
- Задать имя;
- Type — Default;
- Protocol — SAML.

Открыть вкладку Mappers и создать утверждение атрибутов для передачи дополнительных атрибутов пользователя из Keycloak (IDP) в Пассворк (SP):
- Добавление утверждения для передачи email:
- Add predefined mapper → X500 email;
- Открыть добавленное утверждение из шаблона и изменить:
- SAML Attribute Name — email;
- SAML Attribute NameFormat — Basic.
- Добавление утверждения для передачи firstName:
- Add mapper → From predefined mappers → X500 surname;
- Открыть добавленное утверждение из шаблона и изменить:
- Property — firstName;
- SAML Attribute Name — firstName;
- SAML Attribute NameFormat — Basic.

Назначить на созданное приложение (SP) созданный набор настроек (Client scope) — Clients → Пассворк → перейти на вкладку Client scopes → Add client scope:

Выбрать из списка созданный набор passwork_client_scope с Assigned type — Default:

Удалить добавленный по умолчанию шаблон настроек — role_list:

Настройка и заполнение параметров единого входа (SSO) в Пассворке
Заполнение значений «Атрибуты пользователя»
Авторизоваться в веб-интерфейсе Пассворка, перейти в — Настройки и пользователи → Настройки SSO и заполнить атрибуты сопоставления:
- Атрибут электронной почты — email;
- Атрибут полного имени — firstName.
Заполнение значений «Поставщик удостоверений → Пассворк»
Открыть конфигурацию поставщика услуг (IDP) — Realm settings → General → Endpoints:

Скопировать следующие значения параметров:
- xml
entityID="https://keycloack.passwork.local/realms/master"
<md:SingleLogoutService Location="https://keycloack.passwork.local/realms/master/protocol/saml"/>
<md:SingleSignOnService Location="https://keycloack.passwork.local/realms/master/protocol/saml"/>
Пример xml вывода

Откры ть — Настройки и пользователи → Настройки SSO и заполнить значения:
- Идентификатор (Entity ID) — https://keycloack.passwork.local/realms/master
- Url-адрес входа — https://keycloack.passwork.local/realms/master/protocol/saml
- Url-адрес выхода — https://keycloack.passwork.local/realms/master/protocol/saml
Заполнение значения «Сертификат»
Открыть и скопировать сгенерированный SSL сертификат в base64 формате — Realm settings → Keys → Certificate:

Скопированный SSL сертификат поместить в соответствующее поле — Настрой ки и пользователи → Настройки SSO.
Открыть окно авторизации в веб-интерфейсе Пассворка и выполнить вход через SSO для проверки корректной настройки:

Возможные ошибки
В случае возникновения ошибок, они будут расположены в PHP лог-файле.
Ответ от SSO не может быть корректно расшифрован, так как неправильно скопирован отпечаток сертификата или это отпечаток неверного сертификата:
OneLogin_Saml2_Error: invalid_response LastErrorReason: Signature validation failed. SAML Response rejected in /var/www/app/modules/Admin/SSO/SsoController.php:78\nStack trace:\n#0 [internal function]: Passwork\\Modules\\Admin\\SSO\\SsoController->acsAction()\n#1 [internal function]: Phalcon\\Dispatcher\\AbstractDispatcher->callActionMethod()\n#2 [internal function]:Phalcon\\Dispatcher\\AbstractDispatcher->dispatch()\n#3 /var/www/public/index.php(91): Phalcon\\Mvc\\Application->handle()\n#4 {main}
Неправильно указано текущее значение хоста в параметре APP_URL файла config.env:
OneLogin_Saml2_Error: Invalid array settings: sp_acs_url_invalid, sp_sls_url_invalid in /var/www/app/vendors/php-saml/lib/Saml2/Settings.php:122\nStack trace:\n#0 /var/www/app/vendors/php-saml/lib/Saml2/Auth.php(152): OneLogin_Saml2_Settings->__construct()\n#1 /var/www/app/modules/Admin/SSO/SsoService.php(53): OneLogin_Saml2_Auth->__construct()\n#2 /var/www/app/modules/Admin/SSO/SsoController.php(33): Passwork\\Modules\\Admin\\SSO\\SsoService->getAuth()\n#3 [internal function]: Passwork\\Modules\\Admin\\SSO\\SsoController->loginAction()\n#4 [internal function]: Phalcon\\Dispatcher\\AbstractDispatcher->callActionMethod()\n#5 [internal function]: Phalcon\\Dispatcher\\AbstractDispatcher->dispatch()\n#6 /var/www/public/index.php(91): Phalcon\\Mvc\\Application->handle()\n#7 {main}, referer:
У пользователя отсутствует атрибут, по которому выполняется вход:
OneLogin_Saml2_Error: invalid_response LastErrorReason: The status code of the Response was not Success,was Responder -> urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy in /var/www/app/modules/Admin/SSO/SsoController.php:78\nStack trace:\n#0 [internal function]:Passwork\\Modules\\Admin\\SSO\\SsoController->acsAction()\n#1 [internal function]: Phalcon\\Dispatcher\\AbstractDispatcher->callActionMethod()\n#2 [internal function]:Phalcon\\Dispatcher\\AbstractDispatcher->dispatch()\n#3 /var/www/public/index.php(91): Phalcon\\Mvc\\Application->handle()\n#4 {main}