Skip to main content

django-sso-oauth

Django OAuth authentication for the admin interface and the frontend.

Replaces the default Django admin login with an OAuth 2.0 / OpenID Connect flow, and provides the same flow for regular (non-staff) site users. After a successful OAuth exchange, the user's session is maintained by a lightweight middleware that maps the OAuth identity to a Django user.

Requirements

  • Python >= 3.6
  • Django >= 3.2
  • requests
  • PyJWT

Installation

pip install django-sso-oauth

Configuration

1. Environment variables

Set the following variables in your .env file or environment:

Variable Description
DJANGO_SSO_OAUTH_BASE_URL Base URL of the OAuth provider (e.g. https://sso.example.com)
DJANGO_SSO_OAUTH_CLIENT_ID OAuth client ID
DJANGO_SSO_OAUTH_CLIENT_SECRET OAuth client secret
DJANGO_SSO_OAUTH_REDIRECT_URL Redirect URI registered with the OAuth provider (e.g. https://yourapp.example.com/sso/callback/)
DJANGO_SSO_OAUTH_AFTER_LOGIN_URL Where to land after an admin login (default: admin:index)
DJANGO_SSO_OAUTH_USER_AFTER_LOGIN_URL Where to land after a frontend login (default: index)
DJANGO_SSO_OAUTH_AFTER_LOGOUT_URL Where to land after logout (default: same as DJANGO_SSO_OAUTH_USER_AFTER_LOGIN_URL)

The three URL variables accept either a URL name (admin:index, dashboard) or an absolute path (/dashboard/). A single DJANGO_SSO_OAUTH_REDIRECT_URL is shared by both the admin and the frontend flow.

2. Add to INSTALLED_APPS

INSTALLED_APPS = [
    ...
    "django_sso_oauth",
]

3. Add middleware

Add OauthSessionMiddleware after AuthenticationMiddleware in your MIDDLEWARE setting:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django_sso_oauth.middleware.OauthSessionMiddleware",  # <-- add here
    ...
]

The middleware only sets request.user when an SSO session is present, so ordinary Django authentication (e.g. a local superuser) keeps working alongside SSO.

4. Wire up URLs

In your project's urls.py, override the default admin login, add the frontend login/logout routes, and add the shared OAuth callback:

from django.contrib import admin
from django.urls import path, include
from django_sso_oauth import views as sso_views

urlpatterns = [
    path("admin/login/", sso_views.login_admin),            # replaces default admin login
    path("user/login/", sso_views.login_user, name="userlogin"),
    path("user/logout/", sso_views.logout_user, name="userlogout"),
    path("admin/", admin.site.urls),
    path("sso/callback/", sso_views.oauth_redirect),        # OAuth callback
    ...
]

Important: admin/login/ must be declared before admin.site.urls so it takes precedence. The sso/callback/ path must match DJANGO_SSO_OAUTH_REDIRECT_URL.

5. Frontend usage

Point Django's LOGIN_URL at the frontend login view so @login_required sends users into the SSO flow:

LOGIN_URL = "/user/login/"

@login_required appends ?next=<original path>, which is carried through the OAuth round trip and honoured on the way back, so users land on the page they originally asked for.

How it works

  1. A user visiting /admin/ is redirected to /admin/login/; a user visiting a @login_required page is redirected to /user/login/.
  2. The login view redirects to the OAuth provider's authorization endpoint with a signed state parameter carrying the target (admin or user) and the next URL.
  3. The provider redirects back to the callback with an authorization code and the state.
  4. oauth_redirect verifies the state (rejecting forged or expired ones), exchanges the code for an access token, decodes the JWT to extract the user's email (upn or unique_name claim), and looks up the corresponding Django user.
  5. The user must exist and be active. For the admin target the user must also be is_staff; otherwise the request is rejected with 403 and no session is created.
  6. The email is stored in the session; OauthSessionMiddleware restores the user on every subsequent request.
  7. /user/logout/ flushes the Django session. The provider's own session is left untouched, so a subsequent login is a silent SSO re-login.

The Django user must already exist in the database. User provisioning is not handled by this package.

Upgrading from 1.x

Version 2.0 is a breaking change:

1.x 2.x
views.login views.login_admin
views.login_user, views.logout_user (new)
middleware.OauthAdminSessionMiddleware middleware.OauthSessionMiddleware
middleware placed after SessionMiddleware must be placed after AuthenticationMiddleware

Also note:

  • The callback now requires a valid signed state parameter. Since the login views generate it, no configuration change is needed — but bookmarked or replayed callback URLs will now 400.
  • The middleware no longer forces request.user to AnonymousUser when there is no SSO session.
  • Error responses now return their intended status code (1.x returned 200 for every error path).

Running the tests

python runtests.py

License

MIT

Download files

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

Source Distribution

django_sso_oauth-2.0.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

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

django_sso_oauth-2.0.0-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file django_sso_oauth-2.0.0.tar.gz.

File metadata

  • Download URL: django_sso_oauth-2.0.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.17

File hashes

Hashes for django_sso_oauth-2.0.0.tar.gz
Algorithm Hash digest
SHA256 533ffd1a0f7140c7878ad7fcf7b57e7486fa91997cb822c922809656de798911
MD5 93cafe4d24df6bc05ffc87219792fef4
BLAKE2b-256 aaf3b96da78d2eba117a742ff4ad3a4e825c97dfb0b48f01b05b2dba69da1d43

See more details on using hashes here.

File details

Details for the file django_sso_oauth-2.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_sso_oauth-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c381d4630353c78e5b3bf29c3eb53f844fed01e82d44505b77e790849ae01c29
MD5 2cae37074048187491fde7aca58b2412
BLAKE2b-256 65887b834f0c4733f849c001e233b78a09535b8a5676e403c671a3d787a84cf0

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 Sentry Error logging StatusPage Status page