Reference
Public API documentation.
Views
- class mozilla_django_oidc_db.views.AdminCallbackView(**kwargs)
Intercept errors raised by the authentication backend and display them.
- get(request: HttpRequest, *args, **kwargs)
Callback handler for OIDC authorization code flow
- class mozilla_django_oidc_db.views.AdminLoginFailure(**kwargs)
Template view in admin style to display OIDC login errors
- class mozilla_django_oidc_db.views.OIDCAuthenticationCallbackView(**kwargs)
Base callback view that retrieves the settings from the config object.
- get_settings(attr: str, *args: Any) Any
Look up the request setting from the database config.
For the duration of the request, the configuration instance is cached on the view.
- class mozilla_django_oidc_db.views.OIDCAuthenticationRequestInitView(*args, **kwargs)
A ‘view’ to start an OIDC authentication flow.
This view class is parametrized with the identifier of the config model, so that the specific configuration can be retrieved and settings such as the identity provider endpoint to redirect the user to can be obtained.
This view is not necessarily meant to be exposed directly via a URL pattern, but rather specific views are to be created from it, e.g.:
>>> digid_init = OIDCAuthenticationRequestInitView.as_view(identifier="digid-oidc") >>> redirect_response = digid_init(request) # Redirect to some keycloak instance, for example.
The
__init__method of the DjangoViewwill add attributes to the view for any args/kwargs passed during init. So the view will have an attributeidentifier. Note that it only does it for attributes that are already defined as class attributes.These concrete views are intended to be wrapped by your own views so that you can supply the
return_urlparameter:def my_digid_login(request): return digid_init(request, return_url=request.GET["next"])
Compared to
mozilla_django_oidc.views.OIDCAuthenticationRequestView, some extra actions are performed:Any Keycloak IdP hint is added, if configured
The
return_urlis validated against unsafe redirectsThe availability of the identity provider endpoint can be checked, if it’s not available, the
mozilla_django_oidc_db.exceptions.OIDCProviderOutageexception is raised. Note that your own code needs to handle this appropriately!
- allow_next_from_query: bool = True
Specify if the url-to-redirect-to may be provided as a query string parameter.
For OIDC auth in the admin, you want to enable this to make URLs like
/oidc/authenticate/?next=/admin/work as expected. For more advanced flows, you may want explicit control over this URL via your own wrapper view:digid_init = OIDCAuthenticationRequestInitView.as_view( identifier="config-identifier", allow_next_from_query=False ) def my_digid_login(request): return digid_init(request, return_url="/some-fixed-url")
- check_idp_availability() None
Hook for subclasses.
Raise
OIDCProviderOutageif the Identity Provider is not available, which your application code needs to handle.The default implementation checks if the endpoint has a status code < 401.
- get(request: HttpRequest, return_url: str = '', *args, **kwargs) HttpResponseRedirect
OIDC client authentication initialization HTTP endpoint
- get_extra_params(request: HttpRequest) GetParams
Add a keycloak identity provider hint if configured.
- get_settings(attr: str, *args: Any) Any
Look up the requested setting from the plugin, which defers to the DB config.
For the duration of the request, the plugin instance is cached on the view.
- identifier: str = ''
The identifier of the config model to get the settings from.
Specify this as a kwarg in the
as_view(identifier=...)class method.
- class mozilla_django_oidc_db.views.OIDCAuthenticationRequestView(*args, **kwargs)
Start an OIDC authentication flow.
This view is pre-configured to use the OIDC configuration included in this library, intended for admin authentication. Enable it in your Django settings with:
OIDC_AUTHENTICATE_CLASS = ( "mozilla_django_oidc_db.views.OIDCAuthenticationRequestView" )
- allow_next_from_query: bool = True
Specify if the url-to-redirect-to may be provided as a query string parameter.
For OIDC auth in the admin, you want to enable this to make URLs like
/oidc/authenticate/?next=/admin/work as expected. For more advanced flows, you may want explicit control over this URL via your own wrapper view:digid_init = OIDCAuthenticationRequestInitView.as_view( identifier="config-identifier", allow_next_from_query=False ) def my_digid_login(request): return digid_init(request, return_url="/some-fixed-url")
- identifier: str = 'admin-oidc'
The identifier of the config model to get the settings from.
Specify this as a kwarg in the
as_view(identifier=...)class method.
- class mozilla_django_oidc_db.views.OIDCCallbackView(**kwargs)
Route to the appropriate callback request handler.
When a callback request is received, the state contains information about the configuration model to use. A particular configuration may require certain view behaviour. This view acts as a centralized entrypoint so that there is only a single callback endpoint required. It ensures that the configuration is extracted from the request.
- get(request: HttpRequest, *args, **kwargs) HttpResponseBase
Extract the state from the request parameters and persist it.
The state is extracted so that it’s available for the authentication backend(s) and the downstream views.
- mozilla_django_oidc_db.views.admin_callback_view(request, *args, **kwargs)
Intercept errors raised by the authentication backend and display them.
- mozilla_django_oidc_db.views.default_callback_view(request, *args, **kwargs)
Base callback view that retrieves the settings from the config object.
Authentication backends
- class mozilla_django_oidc_db.backends.OIDCAuthenticationBackend(*args, **kwargs)
Custom backend modifying the upstream package behaviour.
This backend looks up the configuration to use, which is set on the request by the init view. It does this by grabbing the state query parameter and looking in the session for this key. This key was set by the authentication request view. Scoped inside the state, there is the identifier of the configuration to use.
The authenticate method saves the request on the backend instance.
No configuration is loaded in
__init__()at all, instead we define properties to dynamically look this up. Django instantiates backends a lot, e.g. during permission checks. We only support theauthenticate()entrypoint like the upstream library.- authenticate(request: HttpRequest | None, nonce: str | None = None, code_verifier: str | None = None) AnonymousUser | AbstractBaseUser | None
Authenticate the user with OIDC iff the conditions are met.
Return
Noneto skip to the next backend, raisedjango.core.exceptions.PermissionDeniedto stop in our tracks. Return a user object (real or anonymous) to signify success.
- create_user(claims: JSONObject) AbstractUser
Create an authenticated user.
- filter_users_by_claims(claims: JSONObject) QuerySet
Return all users matching the specified email.
- get_or_create_user(access_token: str, id_token: str, payload: JSONObject) AnonymousUser | AbstractUser | None
Get or create a user based on the tokens received.
- get_settings(attr: str, *args: Any) Any
Override the upstream library get_settings.
Upstream is django-settings based, and we store configuration in database records instead. We look up the configuration from the DB and check if the requested setting is defined there or not. If not, it is taken from the Django settings.
- get_userinfo(access_token: str, id_token: str, payload: JSONObject) JSONObject
Extract the user information, configurable whether to use the ID token or the userinfo endpoint for this
- update_user(user: AbstractUser, claims: JSONObject)
Update existing user with new claims, if necessary save, and return user
- verify_claims(claims: JSONObject) bool
Verify the provided claims to decide if authentication should be allowed.
Models
- class mozilla_django_oidc_db.models.OIDCClient(*args, **kwargs)
Hold the client configuration for the Relying Party (RP).
At minimum, the client credentials need to be configured for the associated OIDC Provider (OP). Additional dynamic configuration options can be specified that are tied to specific use cases.
- exception DoesNotExist
- exception MultipleObjectsReturned
- exception NotUpdated
- property oidc_rp_scopes: str
Scopes should be formatted as a string with spaces
- class mozilla_django_oidc_db.models.OIDCProvider(*args, **kwargs)
Manage the configuration/connection parameters for a single OIDC Provider (OP).
- exception DoesNotExist
- exception MultipleObjectsReturned
- exception NotUpdated
- class mozilla_django_oidc_db.models.UserInformationClaimsSources(*values)
- mozilla_django_oidc_db.models.get_default_scopes() list[str]
Returns the default scopes to request for OpenID Connect logins
- class mozilla_django_oidc_db.fields.ClaimField(*args, **kwargs)
A field to store a path to claims holding the desired value(s).
Each item is a segment in the path from the root to leaf for nested claims.
- class mozilla_django_oidc_db.fields.ClaimFieldDefault(*args, **kwargs)
Callable default for ClaimField.
Django’s ArrayField requires a callable to be passed for the
defaultkwarg, to avoid sharing a mutable value shared by all instances. This custom class provides a straight-forward interface so that defaults can be provided inline rather than requiring a function to be defined at the module level, since lambda’s cannot be serialized for migrations.Usage:
>>> field = ClaimField(default=ClaimFieldDefault("foo", "bar")) >>> field.get_default() # ["foo", "bar"]
- deconstruct()
Return a 3-tuple of class import path, positional arguments, and keyword arguments.
Utils
- mozilla_django_oidc_db.utils.do_op_logout(config: OIDCClient, id_token: str) None
Perform the logout with the OpenID Provider.
Standard: https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout
Warning
Preferably, you should send the user to the configured logout endpoint so they can confirm the logout and any session cookies are cleared. If that is not possible, you can call this helper for server-to-server logout, but there are no guarantees this works for every possible OpenID Provider implementation. It has been tested with Keycloak, but the standard says nothing about server-to-server calls to log out a user.
- mozilla_django_oidc_db.utils.get_groups_by_name(group_names: Iterable[str], sync_groups_glob: str, sync_missing_groups: bool) set[Group]
Gets Django User groups by name.
Optionally creates missing groups that match glob pattern.
- mozilla_django_oidc_db.utils.obfuscate_claims(claims: JSONObject, claims_to_obfuscate: Collection[ClaimPath]) JSONObject
Obfuscates the specified claims in the provided claims object.
Signals
- mozilla_django_oidc_db.signals.populate_oidc_config_models(sender, **kwargs) None
See which OIDC plugins are registered and make sure that the corresponding configuration model exists in the database.
- mozilla_django_oidc_db.signals.set_oidcdb_config_identifier_on_session(sender, user, request, **kwargs)
Record the OIDC config identifier on the session, this is needed so the callback view can retrieve the config in case of a SessionRefresh flow.
Plugins
- class mozilla_django_oidc_db.plugins.AbstractUserOIDCPlugin(identifier: str)
- class mozilla_django_oidc_db.plugins.AnonymousUserOIDCPlugin(identifier: str)
- class mozilla_django_oidc_db.plugins.BaseOIDCPlugin(identifier: str)
Base class/interface for all plugins to implement.
- get_config() OIDCClient
Resolve the instance holding the configuration options.
- get_extra_params(request: HttpRequest, extra_params: GetParams) GetParams
Return (additional)
GETparameters for the redirect to the identity provider.By default, the passed in
extra_paramsare returned unmodified.- Parameters:
extra_params – A mapping of query parameters already produced by
mozilla_django_oidc_db.views.OIDCAuthenticationRequestInitView.
- abstractmethod get_schema() JSONObject
Return the JSON Schema definition for the client configuration options.
Each plugin provides certain behaviour that may have configuration parameters. The configuration parameters are stored in the
optionsJSONField of theOIDCClientmodel.The admin integration needs a JSON Schema definitions to be able to configure and validate the options when editing the client configuration.
- get_setting(attr: str, *args) Any
Look up a particular configuration parameter for the configuration options.
- Parameters:
attr – The setting/configuration parameter to look up.
args – Any additional arguments for the lookup behaviour, typically a default value for missing settings is provided here.
- abstractmethod handle_callback(request: HttpRequest) HttpResponseBase
Return an HttpResponse using a specific callback view.
Typed as
HttpResponseBasebecause that’s the annotation forView.as_view()in django-stubs.For example:
def handle_callback(self, request: HttpRequest) -> HttpResponseBase: return admin_callback_view(request)
- identifier: str
The unique identifier for the plugin.
Typically provided through the
@register(IDENTIFIER)decorator when registering a plugin in downstream code.
- abstractmethod validate_settings() None
Check the validity of the settings in the provider and client configuration.
- Raises:
ImproperlyConfigured – if invalid configuration is detected.
- class mozilla_django_oidc_db.plugins.OIDCAdminPlugin(identifier: str)
Implement the core plugin for admin authentication via OpenID Connect.
- create_user(claims: JSONObject) AbstractUser
Return object for a newly created user account.
- filter_users_by_claims(claims: JSONObject) QuerySet
Return all users matching the specified subject.
- get_schema() JSONObject
Return the JSON Schema definition for the client configuration options.
Each plugin provides certain behaviour that may have configuration parameters. The configuration parameters are stored in the
optionsJSONField of theOIDCClientmodel.The admin integration needs a JSON Schema definitions to be able to configure and validate the options when editing the client configuration.
- get_username(claims: JSONObject, *, raise_on_empty: bool = False) str
Given the claims, extract the username value.
- handle_callback(request: HttpRequest) HttpResponseBase
Return an HttpResponse using a specific callback view.
Typed as
HttpResponseBasebecause that’s the annotation forView.as_view()in django-stubs.For example:
def handle_callback(self, request: HttpRequest) -> HttpResponseBase: return admin_callback_view(request)
- update_user(user: AbstractUser, claims: JSONObject) AbstractUser
Update existing user with new claims, if necessary save, and return user.
This method checks dynamic settings, which are provided by our
OIDCClientmodel. If the respective fields do not exist on the config model being used, you must make sure they exist as Django settings.
- validate_settings()
Check the validity of the settings in the provider and client configuration.
- Raises:
ImproperlyConfigured – if invalid configuration is detected.
- verify_claims(claims: JSONObject) bool
Verify the provided claims to decide if authentication should be allowed.
Tests
- class mozilla_django_oidc_db.tests.mixins.OIDCMixin
Helpers around mozilla-django-oidc and mozilla-django-oidc-db.
The post-migrate hook populates the pre-defined OIDC clients and providers, which makes the developer experience in (unit) tests worse because you can’t easily update or patch the configurations, since the factories perform a get_or_create rather than update_or_create. We resolve this by removing all records in the test method setup.
It also automatically installs a mock for the random string generation used for the state and nonce values, as these need to be stable to properly work together with VCR request matching.
- mozilla_django_oidc_db.tests.mixins.mock_random_state_and_nonce()
Mock the state & nonce random value generation
Needed so that we get predictable URLs to match with VCR.
Keycloak helpers taken from mozilla-django-oidc-db::tests/utils.py & pytest fixtures.
These help dealing with/stubbing out OpenID Provider configuration.
The Keycloak client ID/secret and URLs are set up for the config in docker/docker-compose.keycloak.yml. See the README.md in docker/keycloak/ for more information.
- mozilla_django_oidc_db.tests.utils.keycloak_login(login_url: str, username: str = 'testuser', password: str = 'testuser', host: str = 'http://testserver/', session: Session | None = None) str
Test helper to perform a keycloak login.
- Parameters:
login_url – A login URL for keycloak with all query string parameters. E.g. client.get(reverse(“login”))[“Location”].
- Returns:
The redirect URI to consume in the django application, with the
codestatequery parameters. Consume this withresponse = client.get(url).