В статье мы рассмотрим, как настроить собственный Service Provider (SP) в Grails приложении для SAML 2.0 identity provider (idP) и с его помощью осуществить интеграции SSO. В роли idP будет выступать OpenAM сервер, в роли SP — Grails приложение с установленным grails-spring-security-saml дополнением.
Немного теории
SAML (англ. Security Assertion Markup Language — язык разметки декларации безопасности) — язык разметки, основанный на языке XML. Технология разработана для обмена данными об аутентификации и авторизации между защищенными доменами, в частности между поставщиком учётных записей (сокр. IdP от англ. identity provider) и поставщиком сервиса (сокр. SP от англ. Service provider). SAML — это открытый стандарт данных. Одной из важных проблем, которую пытается решить SAML, является обеспечение сквозной аутентификации (Технология единого входа, Single Sign On) при работе через Web-браузер.
Настройка сервера OpenAM (identity provider)
1. Загружаем OpenAM, деплоим OpenAM.war на tomcat. Заходим на url сервера, например http://localhost:8090/OpenAM/, выполняем установку.
- Создаем Custom Configuration с OpenAM User Data Store в качестве хранилища пользователей.
- Заходим с пользователем amAdmin.
2. Генерация и установка ключей на сервер.
OpenAM поставляется с хранилищем ключей по умолчанию. При установке рекомендуется заменить их.
1. Для генерации нового ключа и хранилища ключей используем keytool:
keytool -genkeypair -alias mykey -keyalg RSA -keysize 1024 -validity 365 -storetype JKS -keystore keystore.jks
2. Теперь необходимо зашифровать ключи (хранилище и пароль) с помощью SSOAdm, чтобы возможно было использовать в OpenAM:
openam/bin/ampassword -e .keypass # for private key openam/bin/ampassword -e .storepass # for keystore
3. Переместить новые файлы (keystore.jks, .storepass, .keypass) в директорию ~/openam/openam и перезаписать предыдущие файлы.
4. Перезагрузить OpenAM
- Настройка IDP
1. Во вкладке Access Control создаем новый Realm1. Выбираем его и добавляем пользователей в Subjects.
2. Обязательно после того, как добавили пользователя, необходимо добавить email, поскольку он будет использоваться при авторизации.
3. Во вкладке Federation создаем новый Circle of Trust: COT с реалмом Realm1.
4. На главной странице выбираем Create hosted Identity Provider.
5. Заполняем Realm: Realm1, Name: http://localhost:8090/OpenAMIdp, Existing Circle of Trust: COT, Signing Key: ключ для подписей и шифрования.
6. Теперь по адресу http://localhost:8090/OpenAM/saml2/jsp/exportmetadata.jsp?entityid=http://localhost:8090/OpenAMIdp&realm=/Realm1 будет доступен xml файл с метаданными для idP.
Установка и настройка дополнения grails-spring-security-saml
- Устанавливаем grails-spring-security-saml. Добавляем в BuildConfig.groovy следующее:
plugins { ... compile ":spring-security-saml:1.0.0.M20" ...
- Импортируем сертификат с idP:
keytool -import -alias myIdp -keystore samlKeystore.jks -file Idp.cer ...
- Генерируем ключи для нашего SP:
keytool -genkey -alias apollo -keyalg RSA -keystore samlKeystore.jks ...
Вспомогательные команды keytool:
Список ключей:
keytool -list -v -keystore samlKeystore.jks
Удаление ключей:
keytool -delete -alias badKey -keystore samlKeystore.jks
- Настройка дополнения. В Config.groovy добавляем следующие настройки.
grails.plugins.springsecurity.saml.active=true grails.plugins.springsecurity.saml.responseSkew=300 grails.plugins.springsecurity.saml.active=true grails.plugins.springsecurity.saml.responseSkew=300 //Specifies the maximum permitted time between the timestamps in the SAML Response and the clock on the Jive instance. grails.plugins.springsecurity.saml.afterLoginUrl = '/' grails.plugins.springsecurity.saml.afterLogoutUrl = '/search' grails.plugins.springsecurity.saml.metadata.url = '/saml/metadata'
2. Настройки авто-создания
grails.plugins.springsecurity.saml.autoCreate.active = true //Автоматическое создание пользователей в БД, при аутентификации через плагин grails.plugins.springsecurity.saml.autoCreate.assignAuthorities=true //Автоматические назначение прав из сообщения SAML.
3. Настройки ключей
grails.plugins.springsecurity.saml.keyManager.storeFile = 'classpath:security/samlKeystore.jks' grails.plugins.springsecurity.saml.keyManager.storePass = 'nalle123' grails.plugins.springsecurity.saml.keyManager.passwords = [ apollo: 'nalle123' ] grails.plugins.springsecurity.saml.keyManager.defaultKey = 'apollo'
- Генерация метаданных.
При помощи дополнения сгенерируем мета-данные для SP. Запускаем сервер. По адресу localhost:8080/myApp/metadata доступен UI для генерации метаданных. После генерации мета-данных, сохраним их в sp.xml, для использования в настройках.
Список настроек на странице:
Store for the current session: - необходимо выбрать "да", поскольку не всегда возможно загрузить мета-данные.
Entity ID: - Можно использовать url сервера
Entity base URL: - URL, по которому будет доступно приложение.
Entity alias: - Просто сделать уникальным. Используется сервером SP, когда генерируется больше, чем 1 SP.
Include Idp Discovery: - Выключить, если не поддерживает Idp.
SSO Bindings: - Выбрать механизм работы SSO. В случае openAM все 3 поддерживаются.
Security profile: - Определяет способ проверки подписей и шифрования. Рекомендуется выбирать MetaIOP по умолчанию.
Signing key: - Используем наш сгенерированный ключ apollo.
Encryption key: - Используем наш сгенерированный ключ apollo.
SSL/TLS key: - Используем наш сгенерированный ключ apollo.
Все остальные настройки понятны.
Sign metadata: true
Sign sent AuthNRequests: true
Require signed authentication Assertion: true
Require signed LogoutRequest: true
Require signed LogoutResponse: true
Require signed ArtifactResolve: true
- Сохраняем sp.xml в папке grails-app/conf/security/папке.
Туда же копируем файл ipd.xml, который мы сгенерировали при настройке OpenAM сервера.
Добавляем настройки sp и idp в Config.groovy:
grails.plugins.springsecurity.saml.metadata.sp.file = 'security/sp.xml' grails.plugins.springsecurity.saml.metadata.providers = [idp: 'security/idp.xml'] grails.plugins.springsecurity.saml.metadata.defaultIdp = 'idp' grails.plugins.springsecurity.saml.metadata.sp.defaults = [ local: true, alias: 'localSp', securityProfile: 'metaiop', signingKey: 'apollo', encryptionKey: 'apollo', requireArtifactResolveSigned: true, requireLogoutRequestSigned: true, requireLogoutResponseSigned: true ]
- Перезагружаем приложение
и проверяем по адресу localhost:8080/myApp/metadata наличие и настройки service provider и identity provider. На этом заканчивается настройка SP.
Импорт настроек нашего service provider на сервер OpenAM
- Для начала необходимо импортировать сертификат с SP:
keytool -import -alias mySp -keystore keystore.jks -file sp.cer
- Затем на главной странице выбираем Register Remote Service Provider.
Выбираем Realm1 и загружаем наш sp.xml, который сгенерировали ранее.
Поскольку Grails SAML plugin еще в разработке и документации по нему нет, причины возникающих проблем необходимо искать в исходниках.
Полезные ссылки
Итак, мы установили и настроили сервер OpenAM и настроили Grails приложение для работы с SAML. Ниже приведены ссылки на полезные ресурсы по этой тематике.
- Настройка grails-spring-security-saml plugin
- grails-spring-security-saml plugin и исходники
http://grails.org/plugin/spring-security-saml
https://github.com/fpanwaskar/grails-spring-security-saml
- Spring Security Core Plugin for grails и документации
http://grails.org/plugin/spring-security-core
http://grails-plugins.github.io/grails-spring-security-core/docs/manual/guide/single.pdf
- OpenAM сервер
http://forgerock.org/openam.html
- Spring Security SAML src/sample