Подробный гайд: Интеграция Keycloak и ADFS (SAML 2.0)
Важно:
В Keycloak 19+ изменён базовый путь: /auth/realms/ → /realms/. Все URL в гайде указаны для современных версий (20.x–25.x). ADFS рассматривается версии 2016/2019/2022.
Архитектура и выбор протокола
| Компонент | Роль | Протокол |
|---|---|---|
| ADFS | Identity Provider (IdP) | SAML 2.0 (рекомендуется) |
| Keycloak | Identity Broker / SP | SAML 2.0 |
| Приложения | Service Provider | OIDC / SAML / OAuth2 (не влияет на брокер) |
Почему SAML?
ADFS имеет зрелую поддержку SAML 2.0, стабильную работу с атрибутами и корпоративными стандартами. OpenID Connect в ADFS поддерживается с 2016 версии, но часто требует дополнительных настроек и менее стабилен в enterprise-средах.
Предварительные требования
- Keycloak запущен, доступен по HTTPS, админ-доступ активен.
- ADFS настроен, ферма работает, доступен по HTTPS из сети Keycloak.
- Синхронизация времени на обоих серверах (NTP). Расхождение > 30 сек приведёт к ошибке
`NotBefore/NotOnOrAfter`
- Доменные имена резолвятся корректно в обе стороны.
- У вас есть права:
ADFS AdministratorиKeycloak Realm Admin.
Шаг 1: Настройка ADFS (Relying Party Trust)
- Откройте ADFS Management →
AD FS→Relying Party Trusts→Add Relying Party Trust... - Выберите
Claims aware→Start Enter data about the relying party manually→Next- Display name:
Keycloak Broker - Profile:
AD FS 2016 or later(или Legacy, если ADFS 2012R2) - Configure URL: оставьте пустым →
Next
7. Configure Identifier:
Добавьте: `https://<KEYCLOAK_HOST>/realms/<REALM_NAME>`
*(Это Entity ID Keycloak. Без него ADFS отклонит запросы)*
- Configure Multi-factor Authentication:
I do not want to configure...→Next - Choose Issuance Authorization Rules:
Permit all users→Next(ограничения настраиваются отдельно) - Ready to Add Trust:
Next→Close
11. Настройка конечных точек:
Откройте свойства Trust → вкладка `Endpoints` → `Add`
- Endpoint type: `SAML Assertion Consumer`
- Binding: `POST`
- URL: `https://<KEYCLOAK_HOST>/realms/<REALM_NAME>/broker/adfs/endpoint`
- Trusted URL: оставьте как есть
12. Настройка правил выдачи (Claim Rules):
`Edit Claim Rules...` → `Add Rule`
- **Правило 1: Name ID**
Template: `Send LDAP Attributes as Claims`
Attribute store: `Active Directory`
Mapping: `User-Principal-Name` → `Outgoing claim type: Name ID`
Format: `urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress` (или `persistent` по вкусу)
- **Правило 2: Email**
`Transform an Incoming Claim` → `Pass through or filter an incoming claim`
Incoming: `UPN` → Outgoing: `E-Mail Address`
- **Правило 3 (опционально): Группы/Роль**
`Send LDAP Attributes as Claims` → `Token-Groups - Unqualified Names` → `Group`
13. Экспорт метаданных ADFS:
URL для Keycloak: `https://<ADFS_HOST>/FederationMetadata/2007-06/FederationMetadata.xml`
Шаг 2: Регистрация ADFS как Identity Provider в Keycloak
- Зайдите в Keycloak Admin Console → выберите Realm →
Identity Providers→Add provider→SAML v2.0
2. Basic settings:
| Параметр | Значение |
|---|---|
| Alias | adfs |
| Display Name | Войти через ADFS |
| Enabled | ON |
| Sync Mode | IMPORT (создаёт/обновляет пользователя при входе) |
| Store Token | OFF (по умолчанию) |
3. Endpoint & SAML settings:
| Параметр | Значение |
|---|---|
| Single Sign-On Service URL | https://<ADFS_HOST>/adfs/ls/ |
| Single Logout Service URL | https://<ADFS_HOST>/adfs/ls/ |
| Entity ID | http://<ADFS_HOST>/adfs/services/trust |
| NameID Policy Format | Email Address или Unspecified |
| Want Authn Requests Signed | OFF (ADFS обычно не требует подписи запросов) |
| Force POST Binding | ON |
| Validate Signatures | ON |
| Signature Algorithm | RSA_SHA256 |
4. Import Metadata (рекомендуется):
Вставьте URL метаданных ADFS → Import. Keycloak автоматически подставит URL и сертификат подписи.
Если импорт не подтянул сертификат:
- скачайте XML, извлеките
<ds:X509Certificate>→Add certificateв Keycloak.
5. Attribute Importers (сопоставление SAML → Keycloak):
Перейдите во вкладку Mappers (или Attribute importers в новых версиях):
- `Add mapper` → `Attribute Importer`
- **Name:** `email`
`Attribute Name`: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
`User Attribute`: `email`
- **Name:** `username`
`Attribute Name`: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn`
`User Attribute`: `username`
- **Name:** `firstName` / `lastName` (аналогично, если нужно)
6. Save.
Шаг 3: Настройка клиента (опционально, для тестов)
Clients→Create→Client ID:test-app,Protocol:openid-connectValid Redirect URIs:http://localhost:8080/*(или ваш endpoint)Save- В клиенте не требуется дополнительных настроек для работы с IdP. Брокер активен глобально для реалма.
Шаг 4: Тестирование
Прямой вызов брокера
Откройте в браузере:
https://<KEYCLOAK_HOST>/realms/<REALM_NAME>/broker/adfs/endpoint/login
или добавьте подсказку к обычной странице логина:
https://<KEYCLOAK_HOST>/realms/<REALM_NAME>/protocol/openid-connect/auth?kc_idp_hint=adfs&client_id=test-app&redirect_uri=http://localhost:8080&response_type=code
Ожидаемое поведение:
- Редирект на
https://<ADFS_HOST>/adfs/ls/... - Окно входа Windows/AD
- После успешной аутентификации → редирект обратно в Keycloak
- Создание пользователя в реалме (при первом входе) или автоматический вход
- Переход в клиент (
test-app)
Проверка:
Users→View all users→ найдите созданного пользователя. Атрибутыemail,usernameдолжны совпадать с AD.- В Keycloak:
Events→Login→ статусSUCCESS - В ADFS:
Event Viewer→Applications and Services Logs→AD FS→Admin→ ID364(успешная выдача токена)
Шаг 5: Устранение неполадок
| Ошибка | Вероятная причина | Решение |
|---|---|---|
Invalid Audience |
Identifier в ADFS ≠ Entity ID Keycloak | В ADFS Trust → Identifiers добавьте https://<KC>/realms/<REALM> |
Invalid Signature |
Сертификат ADFS не импортирован или истёк | Обновите метаданные или вручную добавьте текущий сертификат подписи в Keycloak |
NameID Policy format not supported |
Формат NameID в ADFS не совпадает с Keycloak | В Keycloak установите Unspecified или в ADFS добавьте правило преобразования NameID в EmailAddress/Persistent |
User not found after login |
Атрибут username не сопоставлен |
Проверьте Claim Rules в ADFS и Mappers в Keycloak. Убедитесь, что UPN передаётся |
Clock skew detected |
Рассинхрон времени > 30 сек | Настройте NTP (w32tm /config /syncfromflags:manual /manualpeerlist:<ntp> && w32tm /resync) |
RelayState mismatch |
Проблемы с редиректом после входа | В Keycloak: Force POST Binding = ON, проверьте Valid Redirect URIs клиента |
Диагностика SAML:
- Установите расширение SAML Tracer (Firefox/Chrome)
- Зафиксируйте
AuthnRequest→SAML Response - Сравните
Issuer,Audience,NameID,AttributeStatementс настройками в обеих системах.
Рекомендации по безопасности
- Всегда используйте HTTPS. SAML без TLS подвержен MITM.
- Включите валидацию подписи в Keycloak (
Validate Signatures = ON). - Ограничьте доступ к ADFS по IP/сети, если Keycloak и ADFS в разных сегментах.
- Настройте SLO (Single Logout) только если требуется. В enterprise часто отключают из-за проблем с сессиями ADFS.
- Регулярно обновляйте сертификаты ADFS и проверяйте их импорт в Keycloak.
- Используйте
Sync Mode: IMPORTс осторожностью: при изменении атрибутов в AD они перезапишутся в Keycloak при следующем входе. Для readOnly-атрибутов используйтеLEGACY.
Чек-лист перед продакшеном
- [ ] Время синхронизировано (NTP)
- [ ] HTTPS работает на обоих хостах
- [ ] ADFS Relying Party Identifier =
https://<KC>/realms/<REALM> - [ ] Assertion Consumer URL =
.../broker/adfs/endpoint - [ ] NameID и Email передаются через Claim Rules
- [ ] Сертификат подписи ADFS импортирован в Keycloak
- [ ]
Validate Signatures = ON - [ ] Тестовый пользователь успешно создаётся/входит
- [ ] Атрибуты сопоставлены корректно