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

Overview

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': '
   
    '
   ,
        'CLIENT_ID': '
   
    '
   ,
        '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. Because the next query parameter does not travel along with the Duo authentication flow, this session variable is not assigned in the middleware, but can be assigned using a custom instruction in your AuthenticationBackend. This is a feature that I plan to add to this package either through a decorator function or other means. If anyone has any ideas on how to implement this, feel free to submit a pull request!

You might also like...
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Rosetta is a Django application that eases the translation process of your Django projects
Rosetta is a Django application that eases the translation process of your Django projects

Rosetta Rosetta is a Django application that facilitates the translation process of your Django projects. Because it doesn't export any models, Rosett

Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.
Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.

Cookiecutter Django Powered by Cookiecutter, Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly. Documentati

Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App 💛 We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

django-quill-editor makes Quill.js easy to use on Django Forms and admin sites
django-quill-editor makes Quill.js easy to use on Django Forms and admin sites

django-quill-editor django-quill-editor makes Quill.js easy to use on Django Forms and admin sites No configuration required for static files! The ent

A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, celery and redis.

Django Channels Websocket Chatbot A Django chatbot that is capable of doing math and searching Chinese poet online. Developed with django, channels, c

A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.
A handy tool for generating Django-based backend projects without coding. On the other hand, it is a code generator of the Django framework.

Django Sage Painless The django-sage-painless is a valuable package based on Django Web Framework & Django Rest Framework for high-level and rapid web

A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a unique id.

Django-URL-Shortener A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a uni

Dockerizing Django with Postgres, Gunicorn, Nginx and Certbot. A fully Django starter project.

Dockerizing Django with Postgres, Gunicorn, Nginx and Certbot 🚀 Features A Django stater project with fully basic requirements for a production-ready

Comments
  • getting error on callback

    getting error on callback

    Hi Adam,

    Thank you for sharing your package and providing very clear instructions.

    I took a django application (https://github.com/mdn/django-locallibrary-tutorial) and confirmed that the standard django authentication was working.

    I then added the changes to the settings.py and urls.py files mentioned in your README.md. When I run it and attempt to login, I get the following error in the browser:

    {"error": "invalid_grant", "error_description": "Invalid redirect URI 'http://127.0.0.1:8000/duo/callback/'."}

    I get the same error using django 3.2 or 4.1.

    I verified that my duo credentials work by using the demo app in https://github.com/duosecurity/duo_universal_python

    Any insight you can provide would be greatly appreciated!

    Kelvin Lim

    opened by kelvinlim 0
Releases(v0.2.0)
Owner
Adam Angle
UC Berkeley EECS '25 | Student Intern at Exquadrum, Inc.
Adam Angle
A pickled object field for Django

django-picklefield About django-picklefield provides an implementation of a pickled object field. Such fields can contain any picklable objects. The i

Gintautas Miliauskas 167 Oct 18, 2022
Easily share data across your company via SQL queries. From Grove Collab.

SQL Explorer SQL Explorer aims to make the flow of data between people fast, simple, and confusion-free. It is a Django-based application that you can

Grove Collaborative 2.1k Dec 30, 2022
Boilerplate Django Blog for production deployments!

CFE Django Blog THIS IS COMING SOON This is boilerplate code that you can use to learn how to bring Django into production. TLDR; This is definitely c

Coding For Entrepreneurs 26 Dec 09, 2022
No effort, no worry, maximum performance.

Django Cachalot Caches your Django ORM queries and automatically invalidates them. Documentation: http://django-cachalot.readthedocs.io Table of Conte

NoriPyt 980 Jan 06, 2023
Django Audit is a simple Django app that tracks and logs requests to your application.

django-audit Django Audit is a simple Django app that tracks and logs requests to your application. Quick Start Install django-audit pip install dj-au

Oluwafemi Tairu 6 Dec 01, 2022
Учебное пособие по основам Django и сопутствующим технологиям

Учебный проект для закрепления основ Django Подробный разбор проекта здесь. Инструкция по запуску проекта на своей машине: Скачиваем репозиторий Устан

Stanislav Garanzha 12 Dec 30, 2022
This is a template tag project for django to calculate in templates , enjoy it

Calculator-Template-Django this is a template tag project for django to calculate in templates , enjoy it Get Started : 1 - Download Source Code 2 - M

1 Feb 01, 2022
Website desenvolvido em Django para gerenciamento e upload de arquivos (.pdf).

Website para Gerenciamento de Arquivos Features Esta é uma aplicação full stack web construída para desenvolver habilidades com o framework Django. O

Alinne Grazielle 8 Sep 22, 2022
Django channels basic chat

Django channels basic chat

Dennis Ivy 41 Dec 24, 2022
Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes

Bleach Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes. Bleach can also linkify text safely, appl

Mozilla 2.5k Dec 29, 2022
A clone of https://virgool.io written in django

Virgool clone A clone of virgool blog written in django Installation first rename the .env.sample to .env and fill it. with docker docker-compose up -

Danial Selmipoor 7 Dec 23, 2022
PEP-484 type hints bindings for the Django web framework

mypy-django Type stubs to use the mypy static type-checker with your Django projects This project includes the PEP-484 compatible "type stubs" for Dja

Machinalis 223 Jun 17, 2022
Basic implementation of Razorpay payment gateway 💳 with Django

Razorpay Payment Integration in Django 💥 In this project Razorpay payment gateway 💳 is integrated with Django by breaking down the whole process int

ScaleReal 12 Dec 12, 2022
REST API with Django and SQLite3

REST API with Django and SQLite3

Luis Quiñones Requelme 1 Nov 07, 2021
Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Blog focused on skills enhancement and knowledge sharing. Tech Stack's: Vue.js, Django and Django-Ninja

Wanderson Fontes 2 Sep 21, 2022
mirage ~ ♪ extended django admin or manage.py command.

mirage ~ ♪ extended django admin or manage.py command. ⬇️ Installation Installing Mirage with Pipenv is recommended. pipenv install -d mirage-django-l

Shota Shimazu 6 Feb 14, 2022
Mobile Detect is a lightweight Python package for detecting mobile devices (including tablets).

Django Mobile Detector Mobile Detect is a lightweight Python package for detecting mobile devices (including tablets). It uses the User-Agent string c

Botir 6 Aug 31, 2022
xsendfile etc wrapper

Django Sendfile This is a wrapper around web-server specific methods for sending files to web clients. This is useful when Django needs to check permi

John Montgomery 476 Dec 01, 2022
Developer-friendly asynchrony for Django

Django Channels Channels augments Django to bring WebSocket, long-poll HTTP, task offloading and other async support to your code, using familiar Djan

Django 5.5k Dec 29, 2022
Hotwired/Turbo Django response helpers

This package provides helpers for server-side rendering of Hotwired/Turbo streams and frames. Disclaimer: the Hotwired/Turbo client libraries are, at

Hotwire for Django 66 Apr 07, 2022