Install
Python modules
Required modules:
--extra-index-url https://git.fs.tum.de/api/v4/groups/django/-/packages/pypi/simple
django-compref-keycloak<2.0.0
Include these lines in your requirements.txt
.
The version pinning allows us to publish a version with breaking changes in the future without breaking all the applications.
URLs
Include the URLs from mozilla-django-oidc
:
from django.views.generic.base import TemplateView
urlpatterns = [
...
path('oidc/', include('mozilla_django_oidc.urls')),
path("login/", TemplateView.as_view(template_name="appname/login.html")), # probably already there
path("login/failed/", TemplateView.as_view(template_name="appname/login_failed.html")), # adapt to your app
...
]
Template for login pages
Build a login page that describes who can login and contains the link to Keycloak:
<a href="{% url 'oidc_authentication_init' %}">Login</a>
And a page that is displayed in case the login is not allowed (for example is the user is federated from an IDP that you do not allow):
<p>You are not allowed to login to the application or your session is expired (feel free to write a more useful error message here).</p>
<a href="/">Back to application</a>
Settings
Several settings need to be configured.
The login page must be configured (probably already there for existing projects). Change the URLs are required for your app, for example:
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL="/"
LOGOUT_REDIRECT_URL="/"
LOGIN_REDIRECT_URL_FAILURE = "/login/failed"
mozilla_django_oidc
and django_compref_keycloak
must be added to the INSTALLED_APPS
somewhere after django.contrib.auth
and before own apps:
INSTALLED_APPS = [
'django.contrib.auth',
...
'mozilla_django_oidc',
'django_compref_keycloak',
...,
'myapp',
]
Configure django_compref_keycloak.backend.CompRefKeycloakAuthenticationBackend as first authentication backend.
AUTHENTICATION_BACKENDS = (
'django_compref_keycloak.backend.CompRefKeycloakAuthenticationBackend',
'django.contrib.auth.backends.ModelBackend', # not necessary, you can remove it
...
)
Add mozilla_django_oidc.middleware.SessionRefresh
middleware after every other middleware involving session and authentication:
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
'mozilla_django_oidc.middleware.SessionRefresh',
]
The following settings belong to the mozilla-django-oidc
module and configure the basic connectivity to our Keycloak.
# realm is either federated-tum.de or fs.tum.de - provided by CompRef
OIDC_OP_AUTHORIZATION_ENDPOINT = "https://auth.fs.tum.de/auth/realms/federated-tum.de/protocol/openid-connect/auth"
OIDC_OP_TOKEN_ENDPOINT = "https://auth.fs.tum.de/auth/realms/federated-tum.de/protocol/openid-connect/token"
OIDC_OP_USER_ENDPOINT = "https://auth.fs.tum.de/auth/realms/federated-tum.de/protocol/openid-connect/userinfo"
OIDC_OP_JWKS_ENDPOINT = "https://auth.fs.tum.de/auth/realms/federated-tum.de/protocol/openid-connect/certs"
# We have OpenID Connect clients configured for testing.
# It is okay to put their secrets to internal git repositories, but not to public ones!
# These test clients only accept http://localhost:8000 as redirect URL.
OIDC_RP_CLIENT_ID = "..." # provided by CompRef and overwritten for prod deployment
OIDC_RP_CLIENT_SECRET = "..." # provided by CompRef and overwritten for prod deployment
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_STORE_ID_TOKEN = True
ALLOW_LOGOUT_GET_METHOD = True
OIDC_USERNAME_ALGO = "django_compref_keycloak.backend.generate_username"
OIDC_OP_LOGOUT_URL_METHOD = "django_compref_keycloak.backend.logout_url"
Finally, we need to configure who is allowed to log in and which privileges should be assigned to these users.
# Allowed federated identity providers
# fs.tum.de accounts
COMPREF_KEYCLOAK_FEDERATED_IDP = {
# for fs.tum.de realm
"fs.tum.de-internal": {
# allow login with fs.tum.de account?
"enabled": True,
# restrict login to LDAP groups (empty = allow everyone)
"active_groups": ["compref", "set"],
# grant superuser privileges for these LDAP groups (empty = is_staff is not touched, also not removed!)
"staff_groups": ["compref"],
# grant superuser privileges for these LDAP groups (empty = is_superuser is not touched, also not removed!)
"superuser_groups": ["compref"],
# sync LDAP groups to Django groups
"sync_groups": True,
},
# for federated-tum.de realm
"fs.tum.de": {
# allow login with fs.tum.de account?
"enabled": True,
# restrict login to LDAP groups (empty = allow everyone)
"active_groups": [],
# grant superuser privileges for these LDAP groups (empty = is_staff is not touched, also not removed!)
"staff_groups": ["users"],
# grant superuser privileges for these LDAP groups (empty = is_superuser is not touched, also not removed!)
"superuser_groups": ["users"],
# sync LDAP groups to Django groups
"sync_groups": True,
},
"shibboleth.tum.de": {
"enabled": True, # allow login with TUM account?
"active": {
# affiliations: student, alum, employee (more values possible - these are the important ones)
# empty = allow everyone and following settings are ignored!
"affiliations": ["student", "employee"],
# we can restrict the school for students (empty = allow every student)
# only checked if "student" is included in affiliations
"org_student": ["TUINFIN"],
# we can restrict the school for employees (empty = allow every employee)
# only checked if "employee" is included in affiliations
"org_employee": [],
}
# note: is_staff/superuser are not touched (= also not set to False)
}
}
Data for Keycloak (for CompRef)
Callback URLs:
https://app.fs.tum.de/oidc/callback/
(for login)https://app.fs.tum.de/
(redirect after logout)