Plugging in additional auth mechanism to Django admin login

Image credits : https://unsplash.com/photos/aiyBwbrWWlo

We all are very fond of Django admin interface. It simplifies lot of efforts in deploying the application for a developer who has least idea about the asynchronous UI. The beauty of Django admin interface is in the fact that with a very minimalist UI coding ( without even touching HTML, CSS, JavaScript), you can bring up a web interface which offers rich interaction to the user. Authentication to access admin interface is based on users objects present in table django_auth_users of Django. CRUD operation on this table can only be performed by using python script “manage.py”. In this post, I will be walking through the steps involved in custom backend logic access for admin interface. This will allow the users to integrate the admin login interface to any other authentication method such as IAM.


I will demonstrate the process with the help of the following Django project directory.

project_name/
├── project_name/
│ ├── admin.py
│ ├── urls.py
│ ├── uwsgi.py
│ └── __init__.py
└── app/
├── admin.py
├── urls.py
├── models.py
└── ...

Suppose you have a very simple model in your application’s models.py .

app/models.py

Then the default admin.py will look like.

app/admin.py

This admin file we will register a model, MyModel to admin interface and this will make the model to be visible for adding/updating/deleting MyModel objects directly to the db.


Now we will start the process of hooking the admin login page using Django’s custom authentication backend.

  1. To begin with that, we will create a file name backend.py in our application folder. This will store the custom backend logic for our application and will have the following content.
backend.py

This file contains the definition of class that defines two methods get_user. and authenticate. Once those methods are defined in any class, that class becomes a proper candidate for authentication backend. I also have one more global method my_portal_authenticate, which is the core implementation of how the username and password entered by the user can be authenticated by Django login mechanism and will be maintained for the entire session. One thing to note here is that, I am saving the new USER to the django_auth_user tables if the user have logged in for the first time. This is important because Django admin backend (the default one) is strictly coupled with the Django User Model and we are overriding the behavior of default backend. This also allows the service backend to retrieve the session user. Our workaround will be to hook the admin default site with the custom django AdminSite object then, allow this AdminSite object to use this Custom Backend that we have just coded in backend.py.

2. Create a login form to call the custom backend functionality which will be converted to Admin login form later, in the file say login.py in your app directory. This file will implement a class which will create Django form to override default login authentication method.

app/login.py

3. Change the default admin login form using Django AdminSite.

New Version of admin.py

4. The last step is to inform Django urls to the use the Custom login AdminSite object instead of the default one. Go to urls.py in your project settings not in applications settings and add the following stuff to it.

urls.py

We also have to update the AUTHENTICATION_BACKENDS to update the custom backend to the backend that we have implemented. Update the project_name/settings.py with the new variable.

Finally required changes are done.

Access your admin site as usual. If you are running it on localhost, then play with http://localhost:8000