Skip to main content

A Django authentication backend for Microsoft Entra ID

Project description

Entra ID Authentication for Django

Fork of the excellent django-auth-adfs package, with additional functionality.

PyPI version Python versions Django versions

A Django authentication backend for Microsoft Entra ID (formerly Azure AD) and ADFS. This is a fork of django-auth-adfs.

Features

  • Integrates Django with Microsoft Entra ID (Azure AD) or Active Directory Federation Services (ADFS).
  • Provides seamless single sign on (SSO) for your Django project.
  • Auto creates users and adds them to Django groups based on info received from the identity provider.
  • Includes TokenLifecycleMiddleware to manage Access, Refresh, and On-Behalf-Of (OBO) tokens in the user session, enabling delegated API access (e.g., Microsoft Graph). See Token Lifecycle docs for details. (Note: Link might need adjustment)
  • Django Rest Framework (DRF) integration: Authenticate against your API with an access token.

Installation

Python package:

pip install django-entra-auth

In your project's settings.py add these settings.

AUTHENTICATION_BACKENDS = (
    ...
    'django_entra_auth.backend.AdfsAuthCodeBackend',
    ...
)

INSTALLED_APPS = (
    ...
    # Needed for the auth redirect URI and static files to function
    'django_entra_auth',
    ...
)

# Basic configuration for Entra ID
# checkout the documentation for more settings
ENTRA_AUTH = {
    # For Entra ID, use 'login.microsoftonline.com/<your-tenant-id>'
    "SERVER": "login.microsoftonline.com/<your-tenant-id>",
    "CLIENT_ID": "your-application-client-id",
    "RELYING_PARTY_ID": "your-application-client-id", # Often same as CLIENT_ID for Entra ID
    # OIDC Audience ("aud" claim). For Entra ID, LIENT_ID
    "AUDIENCE": "your-application-client-id",
    # Set to False for Entra ID. Provide path for ADFS.
    "CA_BUNDLE": False,
    "CLAIM_MAPPING": {"first_name": "given_name",
                      "last_name": "family_name",
                      "email": "email"}, # Adjust based on claims from your provider
    # See documentation for TokenLifecycleMiddleware settings like:
    # "TOKEN_REFRESH_THRESHOLD", "STORE_OBO_TOKEN", "TOKEN_ENCRYPTION_SALT",
    # "LOGOUT_ON_TOKEN_REFRESH_FAILURE"
}

# Configure django to redirect users to the right URL for login
LOGIN_URL = "django_entra_auth:login"
LOGIN_REDIRECT_URL = "/" # Or wherever users should land after login

########################
# OPTIONAL SETTINGS
########################

MIDDLEWARE = (
    ...
    # Optional: Automatically manage access/refresh/OBO tokens in the session
    # Must be AFTER SessionMiddleware and AuthenticationMiddleware
    'django_entra_auth.middleware.TokenLifecycleMiddleware',
    # With this you can force a user to login without using
    # the LoginRequiredMixin on every view class
    #
    # You can specify URLs for which login is not enforced by
    # specifying them in the LOGIN_EXEMPT_URLS setting.
    'django_entra_auth.middleware.LoginRequiredMiddleware',
)

# Specify URLs exempt from LoginRequiredMiddleware (if used)
# LOGIN_EXEMPT_URLS = (
#     r'^/about/.*$',
#     r'^/legal/.*$',
# )

In your project's urls.py add these paths:

from django.urls import path, include

urlpatterns = [
    ...
    path('oauth2/', include('django_entra_auth.urls')),
]

This will add these paths to Django:

  • /oauth2/login where users are redirected to, to initiate the login with the identity provider.
  • /oauth2/login_no_sso where users are redirected to, but forcing a login screen.
  • /oauth2/callback where the identity provider redirects back to after login. Ensure your redirect URI in Entra ID/ADFS is set to this.
  • /oauth2/logout which logs out the user from both Django and the identity provider (if supported by provider).

Below is sample Django template code to use these paths depending if you'd like to use GET or POST requests. Logging out via GET was deprecated in Django 4.1.

  • Using GET requests (Login only):

    {# Logout requires POST #}
    <a href="{% url 'django_entra_auth:login' %}">Login</a>
    <a href="{% url 'django_entra_auth:login-no-sso' %}">Login (no SSO)</a>
    
  • Using POST requests:

    <form method="post" action="{% url 'django_entra_auth:logout' %}">
        {% csrf_token %}
        <button type="submit">Logout</button>
    </form>
    <form method="post" action="{% url 'django_entra_auth:login' %}">
        {% csrf_token %}
        <input type="hidden" name="next" value="{{ next }}">
        <button type="submit">Login</button>
    </form>
    <form method="post" action="{% url 'django_entra_auth:login-no-sso' %}">
        {% csrf_token %}
        <input type="hidden" name="next" value="{{ next }}">
        <button type="submit">Login (no SSO)</button>
    </form>
    

Contributing

Contributions to the code are more then welcome. For more details have a look at the CONTRIBUTING.rst file.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_entra_auth-1.16.0.tar.gz (4.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_entra_auth-1.16.0-py3-none-any.whl (22.7 kB view details)

Uploaded Python 3

File details

Details for the file django_entra_auth-1.16.0.tar.gz.

File metadata

  • Download URL: django_entra_auth-1.16.0.tar.gz
  • Upload date:
  • Size: 4.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for django_entra_auth-1.16.0.tar.gz
Algorithm Hash digest
SHA256 6b951142a8486fb7c2696b4c061b208e81f0d2098e4dac4b10eba5ac410347ac
MD5 e4d1759ba8cb39b6f76d65606a50240b
BLAKE2b-256 2162cceeae66aff0cc76b4098d3bf324d674a42aa2b15b71a233234bcb4a6807

See more details on using hashes here.

File details

Details for the file django_entra_auth-1.16.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_entra_auth-1.16.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f06fcd0ce5f0152e37d0985f4197a2692eea7f929eaa5a7b85cadf90e749c721
MD5 9370e17cd43fe173e24d9b3213c601e0
BLAKE2b-256 a8b85999cf1e1bb677e137efe7abd3e1bd0a8936fac43c1c69906a77cadeac8c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page