This app allows a Django project to be a SAML SP without running shibd and apache mod_shib. The key dependency is the python3-saml package. For easier development and testing, the app also supports configuring a mocked SAML-authenticated session.
Add required settings, and configure the saml_login
URL in uw_saml.urls.py
to be the LOGIN_URL in your
project/settings.py
:
INSTALLED_APPS = ['uw_saml',]
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.RemoteUserBackend',]
MIDDLEWARE = ['django.contrib.auth.middleware.PersistentRemoteUserMiddleware',]
from django.urls import reverse_lazy
LOGIN_URL = reverse_lazy('saml_login')
This app uses Django settings to configure the SP and IdP. Copy the UW_SAML
setting dict in conf/settings.py
to your project/settings.py
.
You will need to update these settings to the correct values for your SP:
sp.entityId
sp.x509cert
sp.assertionConsumerService.url
sp.singleLogoutService.url
Also, be sure to set strict: True
for production usage!
Add the uw_saml URLs to your project/urls.py
:
path('saml/', include('uw_saml.urls')),
Register your app with the UW Service Provider Registry
To mock a SAML-authenticated session in your app, add the setting
MOCK_SAML_ATTRIBUTES
to project/settings.py
. When this setting is
present, mocking takes precedence over the live SAML workflow.
The value of the setting is a SAML attribute set, representing the
desired attributes for the mocked user:
MOCK_SAML_ATTRIBUTES = {
'uwnetid': ['javerage'],
'affiliations': ['student', 'member'],
'eppn': ['[email protected]'],
'scopedAffiliations': ['[email protected]', '[email protected]'],
'isMemberOf': ['u_test_group', 'u_test_another_group'],
}
To mock a SAML-authenticated session in your app change the
AUTHENTICATION_BACKENDS
to include the mock backend.
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
Also add the following:
DJANGO_LOGIN_MOCK_SAML = {
'NAME_ID': 'mock-nameid',
'SESSION_INDEX': 'mock-session',
'SAML_USERS': [
{
"username": <some username>,
"password": <some password>,
"email": <some email>,
"MOCK_ATTRIBUTES" : {
'uwnetid': [<some username>],
'affiliations': ['student', 'member'],
'eppn': ['[email protected]'],
'scopedAffiliations': ['[email protected]', '[email protected]'],
'isMemberOf': [
'u_test_group', 'u_test_another_group'
],
}
}
]
}
replace <some username>
, <some password>
, <some email>
with the values you want.
You will use these to login when in mock mode. You can add more mock users by appending
to the SAML_USERS
array in UW_SAML_MOCK
.
Replace:
<some username>
with os.getenv('MOCK_USERNAME', None)
,
<some password>
with os.getenv('MOCK_PASSWORD', None)
,
<some email>
with os.getenv('MOCK_EMAIL', None)
Create a .env
file and add this:
MOCK_USERNAME=<desired username>
MOCK_PASSWORD=<desired password>
MOCK_EMAIL=<desired emailid>
If you are using docker:
Add the following to your docker-compose inside the main app:
environment:
MOCK_USERNAME: $MOCK_USERNAME
MOCK_PASSWORD: $MOCK_PASSWORD
MOCK_EMAIL: $MOCK_EMAIL
If you are using pipenv it should just work.
If you are using virtual env checkout https://pybit.es/persistent-environment-variables.html
Make sure that:
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', get_random_secret_key())
Create a .env
file and add this:
DJANGO_SECRET_KEY = <50 character random value>
If you are using docker:
Add the following to your docker-compose inside the main app:
environment:
DJANGO_SECRET_KEY: $DJANGO_SECRET_KEY
If you are using pipenv it should just work.
If you are using virtual env checkout https://pybit.es/persistent-environment-variables.html