Простое использование¶
Примеры простого использования будут основаны на демо-приложении.
Получение дополнительных сведений о пользователе¶
Сразу после установки WSO2IS и регистрации нашего приложения не передается никаких дополнительных атрибутов пользователя.
Заполним атрибуты у созданного ранее пользователя WSO2IS.
Идем Home > Configure > Users and Roles > Users
Находим нашего пользователя demo, открываем и редактируем его User Profile.
Затем укажем, какие атрибуты нужно передавать при успешной аутентификации.
Идем Main > Manage > SAML SSO
Находим наше приложение saml2.demo, открываем и редактируем его.
Укажем признак Enable Attribute Profile и добавим несколько Claim. Например:
Примечание
Обращаю внимание, что после создания профиля атрибутов у зарегистрированного поставщика услуг появляется значение Consumer Index. Которое нужно указывать в настройках нашего приложения. Вероятно, можно создать несколько разных профилей атрибутов для одного и того же приложения. Но это пока не поддерживается модулем SSOSP.
Укажем полученный Consumer Index в настройках settings.py:
SSO_CONFIG = { 'idp': 'https://localhost:9443/samlsso', # адрес Identity Provider 'issuer': 'saml2.demo', # код связи между IdP и SP 'acs': 'http://127.0.0.1:8000/sso/acs/', # адрес сервиса ACS 'session_map': 'ssosp.backends.cache', # бэкенд соответствия сессий 'get_user': 'demo.views.get_or_create_user', # получение пользователя 'index': '1537824998', # индекс профиля атрибутов (Consumer Index) }
Атрибуты, после входа пользователя в систему, сохраняются в сессии пользователя. Получим их при отображении страницы приложения в функции default (view.py) и передадим в шаблон:
def default(request): attributes = request.session.get('attributes', {}) tv = { 'user': request.user, 'attributes': attributes, } return render_to_response('default.html', tv)
Добавим отображение атрибутов на странице приложения.
В шаблоне default.html добавим вывод списка атрибутов.
<html> <head><title>Django SAML 2.0 SP</title></head> <body> {% if not user.username %} I don't recognize you! Please login:<br /> <a href="{% url login %}?next={% url default %}">Login</a> {% else %} Welcome, {{ user.username }}!<br /> <ul> {% for name, value in attributes.items %} <li>{{ name }}: {{ value }} {% endfor %} </ul> <hr> <a href="{% url logout %}?next={% url default %}">Logout</a> {% endif %} </body>
Теперь, после входа пользователя, в приложении отображаются атрибуты пользователя из WSO2IS:
SSO и Single Logout¶
При регистрации нашего приложения или позже, можно настроить возможность Единого выхода для этого приложения. Для этого в описании сервисов SSO WSO2IS нужно отметить соответствующий параметр Enable Single Logout.
В самом нашем приложении дополнять ничего не нужно. Выход из приложения обрабатывается модулем SSOSP через сервис ACS.
Для проверки работы достаточно поднять копию демо-приложения, например, на порту 9000. Также, необходимо зарегистрировать в WSO2IS эту вторую копию, но соответственно по другому адресу и с другим параметром Issuer.
Во втором приложении необходимо соответственно поменять настройки issuer, acs и index (если использовался профиль атрибутов) в settings.py.
Если изменилось имя приложения, то надо поправить ссылки get_user и ROOT_URLCONF (у нас стало приложение demo2):
ROOT_URLCONF = 'demo2.urls'
SSO_CONFIG = {
'idp': 'https://localhost:9443/samlsso', # адрес Identity Provider
'issuer': 'saml2.demo2', # код связи между IdP и SP
'acs': 'http://localhost:9000/sso/acs/', # адрес сервиса ACS
'index': '1906473741',
'session_map': 'ssosp.backends.cache', # бэкенд соответствия сессий
'get_user': 'demo2.views.get_or_create_user', # получение пользователя
}
После запуска двух приложений, при входе в первое из приложений будет запрошен логин и пароль пользователя WSO2IS. При входе во второе приложение уже не потребуется вводить логин и пароль (при условии, что это происходит в одном браузере). Вот оно SSO!
Теперь, при выходе из одного из приложений, на второе приложение придет запрос о завершении сессии на адрес ACS. В результате, при обновлении страницы второго приложения пользователь окажется не авторизован. Т.е. пользователь выйдет из обоих приложений.
Подписывание сообщений SAML¶
В IdP сервере WSO2IS есть настройка, которой можно установить возможность использования цифровой подписи SAML-сообщений.
Идем Main > Manage > SAML SSO
Находим наше приложение saml2.demo, открываем и редактируем его.
Enable Assertion Signing - признак говорит о том, что исходящие от IdP сообщения будут внутри подписаны цифровой подписью формата XMLDSIG. Наше приложение может проверять корректность этой подписи.
Enable Signature Validation in Authentication Requests and Logout Requests - признак говорит о том, что приходящие на IdP запросы на вход и выход, будут проверяться по сигнатуре SimpleSign.
Certificate Alias - наименование сертификата, через который будут проверяться входящие запросы. Для проверки поставим “wso2carbon”.
Теперь выгрузим этот сертификат из хранилища сертификатов WSO2IS
keytool -importkeystore -srckeystore ~/wso2is-4.6.0/repository/resources/security/wso2carbon.jks -storepass wso2carbon -destkeystore wso2carbon.p12 -deststoretype PKCS12 -srcalias wso2carbon -srcstorepass wso2carbon
Достанем из сертификата закрытый ключ. При выгрузке потребуется ввести пароль wso2carbon.
openssl pkcs12 -in wso2carbon.p12 -nocerts -nodes | openssl rsa > privkey.pem
Достанем также сертификат, чтобы получить из него публичный ключ. При выгрузке потребуется ввести пароль wso2carbon.
openssl pkcs12 -in wso2carbon.p12 -clcerts -nokeys | openssl x509 -pubkey -noout > pubkey.pem
Теперь для проверки работы с подписями добавим выгруженные ключи в настройки settings.py и укажем признаки необходимость подписи (‘signing’) и проверки подписи (‘validate’):
SSO_CONFIG = {
....
'signing': True,
'validate': True,
'public_key': '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTousMzO
M4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe
0hseUdN5HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXn
RS4HrKGJTzxaCcU7OQIDAQAB
-----END PUBLIC KEY-----''',
'private_key': '''-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCUp/oV1vWc8/TkQSiAvTousMzOM4asB2iltr2QKozni5aVFu81
8MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5HpwvnH/DW8ZccGvk
53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQIDAQAB
AoGAS/+ooju4a9po67zIGTEkqrQmsJC1HAPZo0bOmQK38LRzcps8Bmao9tjjbuVq
ogEj2xgjtHyNPSn3oBUA3v33usJ6YqwVrWsC6FwmZhq8Avsf94qm4hiTHe1AdxWm
ZGTs1eSYc6JnPIp0iVjHEfssIlGN+7LX1Q6kdbCf482dTnUCQQDvLwmtjlUASW84
zL5PEnNCorlcJ8qjGKlbcur2Lrn3vSCyX4cIWMxPNsCGvS2IO1Ctmz7yssnobhX6
iOaFOZVPAkEAnxuSwN4Kdw9Zku8cc7aifnJuEjzuEemM1cmwGSqilL0xUijVeeyq
fyy+1o7VFDa/nWPmmEZSqPNR6utcvLQU9wJAIycmpPtmQsSINDDjR3vOtNx1obW3
coENYwNgxQ3ZBzAkvhKMJg3m+T1yzlq/dmZBVUKb3c+pHSAQ2uGD/9CWwQJAVRy4
6ndc/ce2UQWcIMJINoAcJaF2cRqQfiTAERZfllWGtr6lQ+24XwOeqsQJdCC9bAJu
7nJf8YUIAzUYjNGAjQJBAKskkwcdhzvVcs7llm3+wWEzbMXzvNBmkZGRhDX6jtUI
J4U9RTHivqMeym4vp0mggaD4zc8qzG1NPDOp0p5AxBg=
-----END RSA PRIVATE KEY-----''',
}
Приложение должно работать как прежде.
Бэкенд соответствия сессий¶
В зависимости от необходимости, соответствие django-сессий и SSO-сессий можно хранить разными способами. За это отвечает настройка ‘session_map’ в SSO_CONFIG. В ней указывается бэкенд, реализующий хранение. В модуле доступны два бэкенда:
- ‘ssosp.backends.cache’ - хранение в кэше
- ‘ssosp.backends.db’ - хранение в базе данных
Бэкенд соответствия сессий используется только при входе в систему и при выходе из системы. Поэтому, на к нему не предъявляются требования по скорости работы - эти события не частые. Но к бэкенду предъявляется требование по обеспечению единого хранилища в случае масштабирования приложения. Поэтому, если приложение распределенное, то следует выбирать и настраивать бэкенд соответствия учитывая это.
При хранении соответствия в кэше, используется настроенное django.core.cache хранилище. Соответствие идентификаторов сессий хранятся в ключах с префиксом ‘ssosessionmap.cache.sso’ для SSO-сессии и ‘ssosessionmap.cache.django’ для django-сессии.
При хранении соответствия в базе данных, используется django-модель SSOSession.