Quickstart

Installation

Requirements

  • See the badges for the supported Python and Django versions

  • A PostgreSQL database (we use django.contrib.postgres.fields.ArrayField)

Install

pip install mozilla-django-oidc-db

This will also install the following packages:

  • mozilla-django-oidc

  • django-jsonform

You can optionally install django-setup-configuration support with:

pip install mozilla-django-oidc-db[setup-configuration]

Django settings

Make sure the following libraries are added to your INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "django_jsonform",
    "mozilla_django_oidc",
    "mozilla_django_oidc_db",
    ...
]

Add mozilla_django_oidc_db.backends.OIDCAuthenticationBackend to the AUTHENTICATION_BACKENDS, this backend replaces mozilla_django_oidc.auth.OIDCAuthenticationBackend:

AUTHENTICATION_BACKENDS = [
    ...
    "mozilla_django_oidc_db.backends.OIDCAuthenticationBackend",
    ...
]

Ensure that LOGIN_REDIRECT_URL and LOGOUT_REDIRECT_URL are configured. For example:

LOGIN_REDIRECT_URL = reverse_lazy("admin:index")
LOGOUT_REDIRECT_URL = reverse_lazy("admin:index")

To enable validation of ID tokens by renewing them, add mozilla_django_oidc_db.middleware.SessionRefresh to the middleware, this middleware replaces mozilla_django_oidc.middleware.SessionRefresh:

MIDDLEWARE = [
    # middleware involving session and authentication must come first
    ...
    "mozilla_django_oidc_db.middleware.SessionRefresh",
    ...
]

Furthermore, ensure the following settings are configured:

OIDC_AUTHENTICATE_CLASS = "mozilla_django_oidc_db.views.OIDCAuthenticationRequestView"
OIDC_CALLBACK_CLASS = "mozilla_django_oidc_db.views.OIDCCallbackView"

In order to properly catch admin login errors, add the following to urlpatterns:

from mozilla_django_oidc_db.views import AdminLoginFailure

urlpatterns = [
    ...
    path("admin/login/failure/", AdminLoginFailure.as_view(), name="admin-oidc-error"),
    ...
]

Add the urlpatterns:

urlpatterns = [
    ...
    path("oidc/", include("mozilla_django_oidc.urls")),
    ...
]

Add the login link to your templates:

{% load mozilla_django_oidc_db %}

{% get_oidc_admin_client as admin_oidc_client %}
{% if admin_oidc_client.enabled %}
<div class="submit-row">
    <a href="{% url 'oidc_authentication_init' %}">{% trans "Login with OIDC" %}</a>
</div>
{% endif %}

Usage

Now OpenID Connect can be enabled/disabled via the admin (disabled by default) and the following settings from mozilla-django-oidc for OpenID Connect can be configured in the admin:

  • OIDC_RP_CLIENT_ID

  • OIDC_RP_CLIENT_SECRET

  • OIDC_RP_SIGN_ALGO

  • OIDC_RP_SCOPES (via oidc_rp_scopes_list)

  • OIDC_OP_JWKS_ENDPOINT

  • OIDC_OP_AUTHORIZATION_ENDPOINT

  • OIDC_OP_TOKEN_ENDPOINT

  • OIDC_OP_USER_ENDPOINT

  • OIDC_TOKEN_USE_BASIC_AUTH

  • OIDC_RP_IDP_SIGN_KEY

  • OIDC_USE_NONCE

  • OIDC_STATE_SIZE

In case no value is provided for one of these variables, the default from mozilla-django-oidc will be used (if there is one). A detailed description of all settings can be found in the mozilla-django-oidc settings documentation.

OIDC discovery endpoint

Instead of setting each OIDC endpoint as shown above manually, these endpoints can be derived by setting the Discovery endpoint (ending with a slash). The path .well-known/openid-configuration will be added to this URL automatically.

For more information about the discovery endpoint, refer to the the OIDC spec.

Custom username claim

The path to the claim value that is used for the User.username property can be configured via the admin OIDCClient > admin-oidc, under the field options > user_settings > claim_mappings > username.

If the desired claim is nested in one or more objects, you can specify the segments of the path:

{
    "some": {
        "nested": {
            "claim": "foo"
        }
    }
}

Can be retrieved by setting the username claim (array field) to:

  • some

  • nested

  • claim

If the claim has dots in it, you can specify those in a segment:

{
    "some.dotted.claim": "foo"
}

can be retrieved with:

  • some.dotted.claim

User profile

In order to set other attributes on the User object, these can also be specified in the options > user_settings > claim_mappings setting. This maps the paths to the claim values returned by the OIDC provider to fields on the User model, and whenever a User is created/updated, these fields will be set to the values of these claims.

User information claims source

There are currently two methods to extract information about the authenticated user, controlled by the User information claims extracted from (userinfo_claims_source) option.

  • Userinfo endpoint, this is the default method (this is also the default behavior in mozilla-django-oidc)

  • ID token, to extract the claims from the ID token. This could be preferable in the case where the authentication server passes sensitive claims (that should not be stored in the authentication server itself) via the ID token

Assigning users to groups

When users are created/updated, they can be automatically assigned to Groups by setting the appropriate value for options > groups_settings > claim_mapping, which is the path to the claim value that contains the groups the user is assigned to by the OIDC provider. If options > groups_settings > sync is enabled, local Django user groups will be created for group names present in the groups claim, if they do not exist yet locally.

Additionally, a options > groups_settings > sync_pattern can be supplied to only sync groups with specific names (default *, to match all groups).

Note

The names of the groups in the environment of the OIDC provider must match exactly with the names of the Groups in Django for this to work.

In order to assign specific Django groups to every OIDC authenticated user, the options > groups_settings > default_groups option can be used.

User permissions

If the options > groups_settings > make_users_staff is enabled, every OIDC authenticated user will automatically be made a staff user, allowing them to login to the admin interface.

In order to promote OIDC authenticated users to superusers, the options > groups_settings > superuser_group_names option can be used. This takes a list of group names and will set is_superuser to True if an authenticated user has at least one of these groups in their groups claim. If a user does not have any of these groups in their groups claim, is_superuser will be set to False for that user.

Note

If superuser_group_names is left empty, the superuser status of users will never be altered upon login, allowing for manual management of superusers.

Claim obfuscation

The OIDCAdminPlugin method verify_claims logs the received claims.

In order to not log information from sensitive claims (identifiers, etc.), claims can be obfuscated by setting in the admin the field options > user_settings > sensitive_claims. This field should contain the path to the claim values that are sensitive. The username claim is considered sensitive by default.