Hello,
I am trying to leverage Auth0 in my Django application. I have followed the documentation, but it is not clear to me how to implement this inside of the built-in Django admin interface. I have staff users accessing the admin and I want to ensure that they go through Auth0 to log in for enhanced security (e.g. MFA).
I have found literally no documentation on this nor online tutorials which are helpful. I would really love some guidance here as I’ve been lost for hours trying to understand how to make this work.
Sorry to hear you are having some troubles trying to authenticate your admin users with Auth0. This is not such a trivial thing to do, for different reasons, but there’s a way.
From the logic, if you followed the Auth0 quick start for django you are using authlib, and creating a session using cookies. That’s all great, but Django is not aware of that session and thus it doesn’t recognize your admins.
You need to translate your authlib session into a django one, for that create a new file auth0_backend.py and paste the following code
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
class Auth0Backend(BaseBackend):
def authenticate(self, request, token=None):
request.session["user"] = token
user_info = token.get('userinfo')
username = user_info.get('sub')
if not username:
raise ValueError('username can\'t be blank!')
# The format of user_id is
# {identity provider id}|{unique id in the provider}
# The pipe character is invalid for the django username field
# The solution is to replace the pipe with a dash
username = username.replace('|', '_')
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# Optionally you can add additional parameters when creating the Django user like the name, role, administrative priviledges and more.
# You can also opt to save the user into the database on each login request, syncronizing the latest changes done to the user in the Auth0 database
user = User(username=username)
user.save()
return user
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
Enable your new Authentication backend, by modifying the file settings.py and adding the following line at the end of the file:
def callback(request):
token = oauth.auth0.authorize_access_token(request)
user = auth.authenticate(request, token=token)
if user:
auth.login(request, user)
return redirect(request.build_absolute_uri(reverse("profile")))
return HttpResponse(status=400)
That will make sure you login your user into the django session.
TODO: in the Auth0Backend class, there’s a translation from the Auth0 user to a Django user. In there, there’s no criteria to determine if a user is an admin or not as that would depend on your requirements and how you want to set that up. You can update that method to set any properties from the User object and give it the access your need.