From 459f90380bc96c62c8259aee06bffabd91edfeed Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Mon, 15 Jul 2024 15:14:01 +0200 Subject: [PATCH] :alembic: [#3967] See if we can grab the branch number from eHerkenning This is really hard to test/try out because we don't have a real eherkenning setup with a branch service restriction as far as I can tell... However, piecing together the documentation on: https://afsprakenstelsel.etoegang.nl/Startpagina/v2/interface-specifications-dv-hm (which describes the interface between service provider and makelaar), we should get back the ServiceRestriction SAML attribute if information is available in the MR (machtigingsregister). The examples show that it would not be an encrypted attribute (it sits in the AttributeStatement element): 123456789012 The documentation says it would be one or more restriction, so we're assuming that it returns a list of strings of values after processing, similar to the urn:etoegang:core:ServiceID and urn:etoegang:core:ServiceUUID attributes. --- .../contrib/eherkenning/constants.py | 1 + .../contrib/eherkenning/plugin.py | 23 +++++++++++++++++++ .../contrib/eherkenning/views.py | 12 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/openforms/authentication/contrib/eherkenning/constants.py b/src/openforms/authentication/contrib/eherkenning/constants.py index f58e71489d..4c193b5911 100644 --- a/src/openforms/authentication/contrib/eherkenning/constants.py +++ b/src/openforms/authentication/contrib/eherkenning/constants.py @@ -1,5 +1,6 @@ EHERKENNING_PLUGIN_ID = "eherkenning" EHERKENNING_AUTH_SESSION_KEY = f"{EHERKENNING_PLUGIN_ID}:kvk" EHERKENNING_AUTH_SESSION_AUTHN_CONTEXTS = f"{EHERKENNING_PLUGIN_ID}:authn_contexts" +EHERKENNING_BRANCH_NUMBERS_SESSION_KEY = f"{EHERKENNING_PLUGIN_ID}:branch_numbers" EIDAS_AUTH_SESSION_KEY = "eidas:pseudo" EIDAS_AUTH_SESSION_AUTHN_CONTEXTS = "eidas:authn_contexts" diff --git a/src/openforms/authentication/contrib/eherkenning/plugin.py b/src/openforms/authentication/contrib/eherkenning/plugin.py index 8e8da917b1..81dedbc507 100644 --- a/src/openforms/authentication/contrib/eherkenning/plugin.py +++ b/src/openforms/authentication/contrib/eherkenning/plugin.py @@ -1,3 +1,4 @@ +import logging from typing import Any, NoReturn from django.http import HttpRequest, HttpResponseBadRequest, HttpResponseRedirect @@ -24,9 +25,12 @@ from .constants import ( EHERKENNING_AUTH_SESSION_AUTHN_CONTEXTS, EHERKENNING_AUTH_SESSION_KEY, + EHERKENNING_BRANCH_NUMBERS_SESSION_KEY, EIDAS_AUTH_SESSION_KEY, ) +logger = logging.getLogger(__name__) + _LOA_ORDER = [loa.value for loa in AssuranceLevels] @@ -108,6 +112,7 @@ def handle_return(self, request: HttpRequest, form: Form): "attribute": self.provides_auth, "value": identifier, "loa": self.get_session_loa(request.session), + **self.get_extra_form_auth_kwargs(request.session), } return HttpResponseRedirect(form_url) @@ -115,6 +120,9 @@ def handle_return(self, request: HttpRequest, form: Form): def get_session_loa(self, session): return "" + def get_extra_form_auth_kwargs(self, session) -> dict[str, Any]: + return {} + def logout(self, request: HttpRequest): if self.session_key in request.session: del request.session[self.session_key] @@ -130,6 +138,21 @@ def get_session_loa(self, session) -> str: authn_contexts = session.get(EHERKENNING_AUTH_SESSION_AUTHN_CONTEXTS, [""]) return max(authn_contexts, key=loa_order) + def get_extra_form_auth_kwargs(self, session) -> dict[str, Any]: + branch_numbers = session.get(EHERKENNING_BRANCH_NUMBERS_SESSION_KEY) + if not branch_numbers: + return {} + if (num := len(branch_numbers)) > 1: + # https://afsprakenstelsel.etoegang.nl/Startpagina/v2/interface-specifications-dv-hm + # explicitly mentions that "one or more ServiceRestrictions" can be provided, + # we currently only support one. + logger.warning( + "Got more than one branch number (got %d), this is unexpected!", + num, + ) + branch_number = branch_numbers[0] + return {"legal_subject_service_restriction": branch_number} + def check_requirements(self, request, config): # check LoA requirements authenticated_loa = request.session[FORM_AUTH_SESSION_KEY]["loa"] diff --git a/src/openforms/authentication/contrib/eherkenning/views.py b/src/openforms/authentication/contrib/eherkenning/views.py index b5abdcd9e1..6b93cabed6 100644 --- a/src/openforms/authentication/contrib/eherkenning/views.py +++ b/src/openforms/authentication/contrib/eherkenning/views.py @@ -17,6 +17,7 @@ from .constants import ( EHERKENNING_AUTH_SESSION_AUTHN_CONTEXTS, EHERKENNING_AUTH_SESSION_KEY, + EHERKENNING_BRANCH_NUMBERS_SESSION_KEY, EIDAS_AUTH_SESSION_KEY, ) @@ -126,6 +127,17 @@ def get(self, request): "urn:etoegang:1.9:EntityConcernedID:Pseudo" ] + # Extract the branch number service restriction(s) - this is all super vague and + # we don't seem to have proper test accounts for this... + # See https://afsprakenstelsel.etoegang.nl/Startpagina/v2/interface-specifications-dv-hm, + # section "AttributeStatement" for an example response. + # This translates to a list of strings (12 chars, all digits) + if branch_numbers := attributes.get( + "urn:etoegang:1.9:ServiceRestriction:Vestigingsnr" + ): + logger.info("Got branch numbers: %r", branch_numbers) + request.session[EHERKENNING_BRANCH_NUMBERS_SESSION_KEY] = branch_numbers + # store the authn contexts so the plugin can check persmission when # accessing/creating an object request.session[EHERKENNING_AUTH_SESSION_AUTHN_CONTEXTS] = (