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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 23a0ef9cd9a57cb274ed7f19ccb36d2dd63820f14961b8f8a59a58f048e36569 |
|
MD5 | 32c8d6b3c782377f8093959c86e2d688 |
|
BLAKE2b-256 | 8839228808ee0148edc24ee81493aefd84bab66eb2c19ae82111ac64a8b3fb0f |
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
Algorithm | Hash digest | |
---|---|---|
SHA256 | 45326fb1905ba85e554b0d2f6ac9e87a145750791727c11744e44e00ef6a37d4 |
|
MD5 | 8e80e3aea495f727bb2e6448329db9f9 |
|
BLAKE2b-256 | 5d60aae73c6d4d1ae349d441b23631e0c420e72f3506d4bf95d190568d56d849 |