Using Custom Authentication Backends in Django

Using Custom Authentication Backends in Django

If you’re working in an organization with an established product line that serves live users, supporting a new site with Django probably means integrating with an existing authentication system.

Using Custom Authentication Backends in Django

If you’re working in an organization with an established product line that serves live users, supporting a new site with Django probably means integrating with an existing authentication system. Many organizations use widely-adopted authentication systems provided by services like Google, Facebook, or GitHub. A few Python packages provide authentication integration with these services, but most of them expect you to be handling the final user accounts on with Django. What happens when you need to work with user accounts that live in another system altogether?

In this article, you’ll see the interface that Django exposes for authenticating to an external system. By the end, you should understand the pieces involved in mapping an external system’s information to Django’s native User objects in order to work with them on your own site.

Django’s default authentication

In the Django User Authentication System, we covered the basics of how default authentication works in Django. Ultimately, you can interact with User objects and understand if a user is_authenticated or not. Using the default authentication system, you can make use of many of Django’s built-in features like its login and logout views and password reset workflow.

When working with an external authentication system, you have to manage these pieces yourself. Some of them may not make sense to you depending on how your authentication system works.

Authentication backends

As with many of Django’s systems, authentication is modeled as a plugin system. Django will try to authenticate users through a series of authentication backends. The default backend checks a user’s username and password against all the existing User objects in the database to authenticate them. The AUTHENTICATION_BACKENDS setting is your entrypoint to intercept this workflow and point Django to your external system.

An authentication backend is a class that, minimally, implements two methods:

  • get_user(user_id) — a user_id can be whatever unique identifier your external system uses to distinguish users, and get_user returns either a user object matching the given user_id or None.
  • authenticate(request, **credentials) — the request is the current HTTP request, and the credentials keyword arguments are whatever credentials your external system needs to check if a user should be authenticated or not. This is often a username and password, but it could be an API token or some other scheme. authenticate returns an authenticated User object or None.

Inside your authentication backend’s authenticate method, you can pass along the credentials to your external system via a REST API or another common authentication scheme like LDAP or SAML.

Using the wonderful Yes or No? API, you could build an authentication backend that authenticates a user occasionally if the API permits:

import requests

class FickleAuthBackend:
    def authenticate(self, request, username):
        response = requests.get(
            'https://yesno.wtf/api/'
        ).json()
        return User(username=username, password='') if response['answer'] == 'yes' else None

While authenticate can return a user object or None, it may also return an AnonymousUser object, or raise PermissionDenied to explicitly halt any further authentication checks. This allows for a variety of ways to proceed, and anonymous users may still have certain permissions. You’ll want to account for that in your middleware and views.

If the external user service provides additional information about the user, get_user might be a good place to grab some of that data. You can add attributes to the user object in authenticate before you return it if you’d like, but be careful of how many attributes you add dynamically.

Permissions

I also covered Django’s permission scheme in The Django User Authentication System: when given a user, you can inquire about their permissions generally or against specific objects using the has_perm method. Custom authentication backends can override permission checking methods and Django will check against those first before falling back to its default checks. This allows you to make queries to your external system about permissions in addition to authentication:

... continue with Permissions and check out the code!

Dane Hillard has an upcoming book "Practices of the Python Pro" coming this month (October 2019)

django python web-development web-service

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Python Developers

Are you looking for experienced, reliable, and qualified Python developers? If yes, you have reached the right place. At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, our full-stack Python development services...

Hire Python Developers India

Looking to build robust, scalable, and dynamic responsive websites and applications in Python? At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, we constantly endeavor to give you exactly what you need. If you need to...

Top Python Development Companies | Hire Python Developers

After analyzing clients and market requirements, TopDevelopers has come up with the list of the best Python service providers. These top-rated Python developers are widely appreciated for their professionalism in handling diverse projects. When...

Basic Data Types in Python | Python Web Development For Beginners

In the programming world, Data types play an important role. Each Variable is stored in different data types and responsible for various functions. Python had two different objects, and They are mutable and immutable objects.

For World Class Web Development Services in India visit RB Genie

Do you want excellent and world class web development services for your valuable projects? Contact **RB Genie **now, we have more than 8 years experienced team of web developers, which specializes in overall web design and website development...