Authentication
The authentication module provides plugins to establish the identity of end-users filling out a form. Identifying attributes can then be used by Prefill plugins to retrieve additional details of the citizen or company. Depending on the authentication plugin used, a certain level of assurance regarding the authentication strength can be obtained as well, increasing trust for higher levels.
Python API
The public API serves as an abstraction over the various plugins.
Reference
- class openforms.authentication.service.AuthAttribute(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
core identifying attributes retrieved from the authentication plugins
- class openforms.authentication.service.BaseAuth
The base structure of authentication data.
- plugin: str
The unique identifier of the plugin that inititiated the authentication data.
- openforms.authentication.service.check_user_is_submission_initiator(request: HttpRequest, submission: Submission) bool
Test if the logged in user matches the user who started the submission.
The logged in user is not to be confused with a Django user, but the user stored in the session under
FORM_AUTH_SESSION_KEYafter logging in for a particular form.The session details are compared against
submission.auth_info. A match happens when the same auth plugin and identifier are present on both.Callers must verify that:
Returns
Trueif there’s a match, andFalseotherwise.
Plugin developer reference
See the Python API.
Available implementations
The following plugins are available in Open Forms core.
Demo, DigiD Mock, Outage
Demo plugins, available only to admin users and when demo plugins are enabled in the configuration. They allow simulating various login mechanisms without requiring a real integration.
DigiD
Provides DigiD integration via the SAMLv2 standards. Implemented throught the library django-digid-eherkenning.
eHerkenning and eIDAS
Provides eHerkenning and eIDAS integration via the SAMLv2 standards. Implemented through the library django-digid-eherkenning.
DigiD and eHerkenning/eIDAS via OpenID Connect
DigiD, eHerkenning and eIDAS support through the OIDC protocol rather than SAML. Depends
on an OpenID Connect provider that implements the SAML flows under the hood. Implemented
throught the oidc flavour of the django-digid-eherkenning library.
Organisation (OIDC)
Provides authentication for staff users through their organisation single-sign on. Shares the OpenID Connect configuration for the admin login option, but is exposed to form authentication as well.
Yivi (OIDC)
Yivi authenticates based on attributes (which could be a bsn or kvk-number) disclosed by the end users. As a consequence, we cannot know beforehand which specific claims will be received after authentication.
Configuration is done in the admin via Configuratie > OIDC Clients and then yivi-oidc.
Note
End-users must have the Yivi app installed on their phone.
Warning
Due to technical reasons, Yivi support is currently only available through Signicat.
Form specific configuration
When configuring the Yivi plugin, in the form builder, you can specify which
authentication options are available during login (bsn, kvk and/or pseudo) and which
additional attributes should be requested from the user. See
openforms.authentication.contrib.yivi_oidc.config.YiviOptionsSerializer for
details.
Requesting attributes using the condiscon system
Condiscon is a Yivi-specific way of defining the authentication attributes to request from users. With condiscon you define a multi-layer conditional data structure, which provides users more control over which attributes they do and don’t provide.
openforms.authentication.contrib.yivi_oidc.config.YiviOptionsSerializer.authentication_options
and openforms.authentication.contrib.yivi_oidc.config.YiviOptionsSerializer.additional_attributes_groups
determine which attributes to include in the condiscon parameter.
openforms.authentication.contrib.yivi_oidc.oidc_plugins.YiviPlugin.get_extra_params() retrieves the
authentication backend options and adds the attributes to the authentication request.
As the condiscon scope is form-specific, we need to modify the authentication request scopes dynamically. The scope is shaped following the Signicat parameters scope standard.
Note
Important notes about the Yivi attributes and condiscon!
For the Yivi authentication to be successful, at least one attribute needs to be disclosed.
The order of optional disjunction matters. Make sure that the “empty” option is the last item in the disjunction list.
Example of a valid optional disjunction:
[ [ ["pbdf.pbdf.diploma.degree"], [], ] ]
Authentication result
Which authentication value (bsn, kvk or pseudo) is returned by the plugin depends on the form-specific configuration, and the data provided by the user.
To determine which authentication option was used you have to check the returned claims.
This is done by the _get_user_chosen_authentication_attribute() function; it
checks the returned claims against the configuration for bsn and kvk claims. If
they match, then we know if the user logged in using bsn, kvk or anonymous/pseudo.
Generic OIDC support
The current Yivi setup is limited to Signicat condiscon. For generic OIDC support we need to investigate how other identity providers work with Yivi.
In this context, “generic OIDC” means the normal way of working with OIDC, similar to how DigiD and eHerkenning via OIDC work. Instead of one gigantic bundled scope, you provide individual scopes for the claims you want to be fulfilled.
(This way of working might result into losing the major strength of Yivi; that the user can choose what data they provide.)
Generic OIDC authentication with Signicat
One piece of the puzzle: generic OIDC authentication via Signicat.
Besides the condiscon scope, Signicat also supports generic OIDC authentication. With the generic OIDC authentication you don’t provide a single scope that results in multiple claims; rather, you pass each Yivi attribute as an individual scope item.
For example, the following scope will request the bsn and fullname of a user:
scope: "openid irma-demo.gemeente.personalData.bsn irma-demo.gemeente.personalData.fullname"
Whether other identity providers work similarly is yet to determine.
Reference
Plugin for Yivi authentication
Website: https://yivi.nl/
For development, we can use the Yivi demo attribute sets: https://attribute-index.yivi.app/en/irma-demo.html.
See the project documentation for more information about Yivi authentication.
- class openforms.authentication.contrib.yivi_oidc.config.YiviOptionsSerializer(*args, **kwargs)
- class openforms.authentication.contrib.yivi_oidc.plugin.YiviOIDCAuthentication(identifier: str)
- auth_info_to_auth_context(auth_info: AuthInfo) YiviContext
Plugin custom auth info to auth context handling.
This will be executed during the AuthInfo
to_auth_context_datawhenmanage_auth_contextis set toTrue.
- check_requirements(request: AnyRequest, options: YiviOptions) bool
Check if the request meets requirements
- configuration_options
alias of
YiviOptionsSerializer
- verbose_name: StrOrPromise = 'Yivi via OpenID Connect'
Specify the human-readable label for the plugin.
- class openforms.authentication.contrib.yivi_oidc.oidc_plugins.plugins.YiviPlugin(identifier: str)
- 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.
- get_or_create_user(access_token: str, id_token: str, payload: JSONObject, request: HttpRequest) AnonymousUser
Return a “fake” Django user.
If the claims are valid, we only process them and do not create or update an actual Django user.
- 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.
- 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)
- validate_settings() None
Check the validity of the settings in the provider and client configuration.
- Raises:
ImproperlyConfigured – if invalid configuration is detected.