Skip to main content

A simple Django middleware for Duo Universal 2-factor authentication.

Project description

django-duo-universal-auth

A lightweight middleware application that adds a layer on top of any number of existing authentication backends, enabling 2FA with the user's Duo account using the Universal Prompt after signing in with your Django application.

Note: In order to interface this middleware with Duo, you must create a new Duo Web SDK application from within your organization's Duo Admin Portal and enable the "Show new Universal Prompt" setting. You will acquire a Client ID, Client Secret, and API Hostname, of which you will include in your settings.py file in the format listed below. It is strongly recommended not to hardcode these values in the settings file itself.

From Duo's documentation for protecting applications:

Treat your Secret key or Client ID like a password The security of your Duo application is tied to the security of your Secret key (skey) or Client secret (client_secret). Secure it as you would any sensitive credential. Don't share it with unauthorized individuals or email it to anyone under any circumstances!

Installation

To install the middleware application, use the following pip command (or equivalent for your package manager application):

pip install django-duo-universal-auth

Sample Configuration (in your settings.py file)

First, add the package to your INSTALLED_APPS list variable:

INSTALLED_APPS = [
    # ...
    'duo_universal_auth', # Add this!
]

Next, add the path for the middleware application to the MIDDLEWARE list variable:

MIDDLEWARE = [
    # ...
    'duo_universal_auth.middleware.DuoUniversalAuthMiddleware', # Add this!
]

Then, add a new DUO_UNIVERSAL_AUTH configuration variable:

DUO_UNIVERSAL_AUTH = {
    'MAIN': {
        'DUO_HOST': '<api_hostname>',
        'CLIENT_ID': '<client_id>',
        'CLIENT_SECRET': '<client_secret>',
        'AUTH_BACKENDS': [
            'django.contrib.auth.backends.ModelBackend',
        ],
        'FAIL_ACTION': 'CLOSED'
    }
}

Duo API Callback Setup

Note: This step allows the application to communicate with Duo. If the view is not registered, the application will raise a NoReverseMatch error upon starting the Duo authentication flow.

To create the callback for the API to communicate with, you must add an entry to your urlpatterns variable from within your application's urls.py file (with any prepending path you choose):

from django.urls import path, include

urlpatterns = [
    # ...
    path('duo/', include('duo_universal_auth.urls')), # Add this!
]

Configuration Docs

Configurations for each Duo application are specified within individual dictionary objects inside a parent DUO_UNIVERSAL_AUTH dictionary each containing the following values:

DUO_HOST

Required: True

Represents the API Hostname for your organization's Duo API.

'DUO_HOST': 'api-XXXXXXX.duosecurity.com'

CLIENT_ID

Required: True

Represents the Client ID for your application registered from within the Duo Admin Portal.

'CLIENT_ID': 'DIXXXXXXXXXXXXXXXXXX'

CLIENT_SECRET

Required: True

Represents the Client Secret for your application registered from within the Duo Admin Portal.

'CLIENT_SECRET': 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef'

AUTH_BACKENDS

Required: True

A list of authentication backends that the middleware will work with for the specific application. The Duo authentication middleware will only execute upon a successful authentication result from one of these backends.

'AUTH_BACKENDS': [
    'django.contrib.auth.backends.ModelBackend',
]

FAIL_ACTION

Required: False (Default: 'CLOSED')

How the middleware should respond should the Duo authentication server be unavailable (from failing the preliminary health check).

  • 'CLOSED': Log out the user and return to the login page, disallowing any authentication while Duo servers are unavailable.
  • 'OPEN': Temporarily bypass Duo authentication until the Duo servers become available upon a future authentication attempt.
'FAIL_ACTION': 'CLOSED'

USERNAME_REMAP_FUNCTION

Required: False

An optional one-argument function that takes in the current Django HttpRequest object and returns the current authenticated user's username to send for Duo authentication. If unspecified, the username from HttpRequest.user will be used.

'USERNAME_REMAP_FUNCTION': lambda r: r.user.username  # Mimics default behavior

Post-Authentication Redirect

Once successfully authenticated with Duo, the middleware will automatically redirect the user to the path specified in the DUO_NEXT_URL session variable, falling back to the LOGIN_REDIRECT_URL settings variable if it is not present. This value is automatically assigned in the middleware before redirecting to Duo.

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-duo-universal-auth-0.2.0.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

django_duo_universal_auth-0.2.0-py2.py3-none-any.whl (8.1 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file django-duo-universal-auth-0.2.0.tar.gz.

File metadata

  • Download URL: django-duo-universal-auth-0.2.0.tar.gz
  • Upload date:
  • Size: 7.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for django-duo-universal-auth-0.2.0.tar.gz
Algorithm Hash digest
SHA256 23a0ef9cd9a57cb274ed7f19ccb36d2dd63820f14961b8f8a59a58f048e36569
MD5 32c8d6b3c782377f8093959c86e2d688
BLAKE2b-256 8839228808ee0148edc24ee81493aefd84bab66eb2c19ae82111ac64a8b3fb0f

See more details on using hashes here.

File details

Details for the file django_duo_universal_auth-0.2.0-py2.py3-none-any.whl.

File metadata

  • Download URL: django_duo_universal_auth-0.2.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for django_duo_universal_auth-0.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 45326fb1905ba85e554b0d2f6ac9e87a145750791727c11744e44e00ef6a37d4
MD5 8e80e3aea495f727bb2e6448329db9f9
BLAKE2b-256 5d60aae73c6d4d1ae349d441b23631e0c420e72f3506d4bf95d190568d56d849

See more details on using hashes here.

Supported by

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