Integrate Django with Keycloak
Keycloak is an open source identity and access management (IAM) and single sign on (SSO) solution from Redhat. If you have multiple web applications or services that require authentication, keycloak saves you from having to write the same authentication code over and over again, and allows your users to authenticate against multiple applications without having to log in multiple times. In this post I will show how to set up Keycloak running locally, and how to use it as the authentication provider for a Django application. This post uses Python 3.x.
Setup Keycloak
Keycloak is distributed as a standalone server so is a doddle to get it up and running. Download the latest archive from the Keycloak website (we will be using 2.5.1 for this post), unzip it and run the bin/standalone.sh
file to start the server.
You can now visit http://localhost:8080/auth/ to check your installation is running correctly (it can take a few minutes to start up so don’‘t panic if you get a 404 error initially). Create an administrator user, open the Administration Console and login.
Once logged in you are at the Master
realm. This is the realm used to create other realms. A realm contains all the users, groups etc. associated with a set of applications and services. Hover over the Master
menu item and click on Add realm
.
Call it sample and click create.
Select Users
from the side menu and create a new user called webuser
(this user will be able to log in to the Django app).
Once created, set a temporary password for the user.
Finally we need to create a client
to represent our Django application.
Select Clients
from the side menu and Add a new client. Call it webapp
and hit save.
Finally update the valid redirect uris to be http://localhost:8000/*
(the url of Django running locally).
This is all we need to do to get started.
You can easily theme the log in pages, allow user registration, password resets, email verification, social logins etc. using the admin console so explore and read the documentation to see whats possible.
Set up Django
First we need to install the Django OIDC libraries. These are Python 3 libraries.
$ pip install git+https://github.com/jhuapl-boss/django-oidc.git
$ pip install git+https://github.com/jhuapl-boss/drf-oidc-auth.git
$ pip install git+https://github.com/jhuapl-boss/boss-oidc.git
Next we create a new django project and application.
$ django-admin startproject keycloakexample
$ cd keycloakexample/
$ python manage.py startapp demo
Now we need to modify our settings.py file. Add bossoidc, djangooidc and demo
to our INSTALLED_APPS
list, and add an AUTHENTICATION_BACKENDS
tuple.
INSTALLED_APPS = [
''django.contrib.admin'',
''django.contrib.auth'',
''django.contrib.contenttypes'',
''django.contrib.sessions'',
''django.contrib.messages'',
''django.contrib.staticfiles'',
''bossoidc'',
''djangooidc'',
''demo'',
]
AUTHENTICATION_BACKENDS = (
''django.contrib.auth.backends.ModelBackend'',
''bossoidc.backend.OpenIdConnectBackend'',
)
We also need to add a few settings to setup our OIDC (Keycloak) provider.
auth_uri = "http://localhost:8080/auth/realms/sample"
client_id = "webapp"
public_uri = "http://localhost:8000"
from bossoidc.settings import *
configure_oidc(auth_uri, client_id, public_uri)
Next, make any migrations required by the bossoidc
application and apply all migrations.
$ python manage.py makemigrations bossoidc
$ python manage.py migrate
Now we can add the urls we need. Change urls.py to read
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'''', include(''demo.urls'')),
url(r''^admin/'', admin.site.urls),
url(r''openid/'', include(''djangooidc.urls'')),
]
Finally, lets change our demo app to show the authentication working. Create demo/urls.py
and add the following.
from django.conf.urls import url
from . import views
urlpatterns = [
url(r''^$'', views.index, name=''index''),
url(r''^secure$'', views.secure, name=''secure''),
]
Add the following to demo/views.py
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
def index(request):
return HttpResponse(''You\''re at the index. <a href="/secure">Secure</a>'')
@login_required
def secure(request):
return HttpResponse(''Secure page. <a href="/openid/logout">Logout</a>'')
We can now start our django app as normal.
$ python manage.py runserver
Now when we visit http://localhost:8000
we get a very simple index page. Clicking on the Secure
link will redirect you to the keycloak log in page.
Enter the username and password you previously created. You will then be redirected to a screen asking you to change the temporary password. Once you change the password you will be redirected to the Django secure page.
Conclusion
It is very easy to get started with keycloak and it offers many tried and tested features that would take significant effort to reimplement yourself. Implementing authentication has always been a tedious and difficult to get right task. If you plan to use microservices or multiple web applications as part of your solution, keycloak can save you significant work and prevent your users from having to log in to the multiple different applications.