Makina Django OIDC Tutorials
Getting started
Installation
To install this library the easiest way is to use the pypi package
pip install django-pyoidc
Configuring your SSO
Next, you should configure a client in your identity provider configuration interface.
Warning
Incorrect configuration of your Identity Provider can create security issues. Please make sure you understand the values you input and their impact on the security level of your system.
We provide instructions for Keycloak (version 18 and more), a free and open source Identity Provider maintened by Red Hat.
Keycloak
Start by connecting as your realm admin on the administration interface.
We will create a new client which supports the ‘Authorization Code Flow’. Go to the client list of your realm and click on “Create client”
Set the Client type to OpenID Connect and choose a meaningful Client ID. The other options do not matter for this tutorial.
On the second page, enable Client authentication and the Standard Flow (also named Authorization Code Flow which is the one that we want).
Click on save and your client should be visible in the client list.
You can now configure your URLs. In the following example, the Django application is hosted at app.local:8082.
We configure our client URLs as such :
Root URLandHome URLredirects to the root of our application http://app.local:8082With
Valid redirect URIswe allow the user to be redirected to our application, or the one listening onlocalhost:9091and127.0.0.1:9091(for debug purposes)With
Valid post logout redirect URIsthe user can be redirected to our application after logout : http://app.local:8082/*Web originsis set to + which allows (through CORS) all origins from the redirect URIs
TODO: using a 2nd app at localhost:9091 is confusing, remove that, use a localhost:something, better
Take note of your Client ID and visit the Credentials Page to find your Client Secret. You will need both to configure the OIDC connector.
Congratulation, your Keycloak configuration is complete ! 🎉
Other Identity provider
Configuring your Django project
Install the application
It is now time to configure your Django project.
First, add the library app (django-pyoidc) to your django applications, after django.contrib.sessions and django.contrib.auth :
INSTALLED_APPS = [
"django.contrib.auth",
"django.contrib.sessions",
...
"django-pyoidc"
]
Warning
Do not forget later to run the migrations ! This module requires some extra database storage tables.
Configure a cache backend
You must have a cache backend for this library to work ! The OIDC protocol is very statefull and we use Django cache system to store data. If you want to understand why, you can read the Cache Management page.
For the sake of this tutorial, you can use this cache management snippet (it should be pasted in your settings.py) :
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "unique-snowflake",
}
}
Warning
Do not use those settings in production ! Go read the django documentation for more details.
Configure the library
Note
In this part we use providers as a quick way to generate the library configuration and URL patterns. However you can also configure the settings manually if you wish to dig into the configuration.
First, create a file named oidc.py and instantiate a django_pyoidc.providers.Keyloack20Provider
as this is the provider that should be used with Keycloak.
We have many settings to provide :
op_nameis the name that this library associate internally with your provider.client_idthe client id that you got from your identity providerclient_secretthe client secret that you got from your identity providerkeycloak_base_uriis the URI of your keycloak instancekeycloak_realmis the name of your keycloak realm
Some extra settings are also available :
success_redirectthe default uri where the user is redirected on login successfailure_redirectthe default uri where the user is redirected on login failurelogout_redirectthe default uri that will be used to redirect the user on logoredirect_requires_httpsthe login view allows the user to be redirected to a dynamic URI. This setting enforce HTTPS on this uri.
TODO: provide good defaults for these settings
Here is my configuration for this tutorial :
from django_pyoidc.providers.keycloak import KeycloakProvider
my_oidc_provider = KeycloakProvider(
op_name="keycloak",
client_secret="s3cret",
client_id="demo_django_pyoidc",
keycloak_base_uri="http://keycloak.local:8080/auth/",
keycloak_realm="Demo",
#logout_redirect="http://app.local:8082/",
#failure_redirect="http://app.local:8082/",
success_redirect="http://app.local:8082/user",
redirect_requires_https=False, # useful in dev
)
Note: after Keycloak 17 the auth/ prefix is removed by default on Keycloak base paths.
Here we use a Keycloak where the KC_HTTP_RELATIVE_PATH=/auth setting was set, to maintain compatibility
with an older version. If you did not use that setting in your Keycloak instance the keycloak_base_uri
parameter would simply be “http://keycloak.local:8080/”.
You may have the auto-configuration json link provided, for our example this url is http://keycloak.local:8080/auth/realms/Demo/.well-known/openid-configuration
If you check this json you can extract paths from this file. For example the first information is :
http://keycloak.local:8080/auth/realms/Demo. Everything before the realms keyword is the
keycloak_base_uri that this library needs, the word following realms/ is the keycloak_realm parameter.
Then you can use the methods get_config() and
get_urlpatterns() to easily generate the settings
and url configuration for your provider.
Edit your django configuration to add your configuration to DJANGO_PYOIDC settings :
from .oidc import my_oidc_provider
DJANGO_PYOIDC = {
**my_oidc_provider.get_config(allowed_hosts=["app.local:8082"]),
}
TODO: remove allowed_hosts from this step, should be in settings
Generate the URLs
Finally, add OIDC views to your url configuration (urls.py):
from .oidc import my_oidc_provider
urlpatterns = [
path("auth", include(my_oidc_provider.get_urlpatterns())),
]
This will include 4 views in your URL configuration. They all have a name that derives from the op_name that you used to create your provider.
a
login viewnamed<op_name>-login, here handled on the/auth/loginpatha
logout viewnamed<op_name>-logout, here handled on the/auth/logoutpatha
callback viewnamed<op_name>-callback, here handled on the/auth/callbackpatha
backchannel logout viewnamed<op_name>-backchannel-logout, here handled on the/auth/backchannel-logoutpath
You should now be able to use the view names from this library to redirect the user to a login/logout page.