From 733a8df28034f8f51a298f8e9965f88216b32fc5 Mon Sep 17 00:00:00 2001 From: tmub Date: Thu, 19 Oct 2023 14:38:48 +0300 Subject: [PATCH] Add support to configure accepted method of receiving MSISDN to be sent to MSSP. Available methods are configured in same place as other related configuration. This however requires three authentication flows to be created. Different clients may have different accepted methods and can be configured under Clients -> client name -> Advanced tab -> Authentication flow overrides Possible values: - BOTH (MSISDN allowed to be received from either URL or FORM) - URL (MSISDN must be received from URL) - FORM (FORM is displayed to enter MSISDN) --- .../laverca/MobileidAuthenticator.java | 48 +++++++++++++++---- .../laverca/MobileidAuthenticatorFactory.java | 11 +++++ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticator.java b/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticator.java index b555b66..dba7e0a 100644 --- a/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticator.java +++ b/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticator.java @@ -25,17 +25,26 @@ public MobileidAuthenticator(KeycloakSession session) { @Override public void authenticate(AuthenticationFlowContext context) { + + // Get the configured allowed methods for getting MSISDN + final String allowedMsisdnMethod = context.getAuthenticatorConfig().getConfig().get("allowed-msisdn-method"); + if (allowedMsisdnMethod == null) { + logger.error("Administrator has not configured the acceptable method(s) to receive MSISDN"); + context.failure(AuthenticationFlowError.INTERNAL_ERROR); + return; + } + + // Get the query params String query = context.getUriInfo().getRequestUri().getQuery(); String[] params = query.split("&"); - // Get DTBD from the client, if they sent it. + // Get DTBD and MSISDN from the client, if they sent it. String dtbdValue = null; String msisdn = null; for (String param : params) { if (param.startsWith("dtbd=")) { dtbdValue = param.substring(5); context.getAuthenticationSession().setClientNote("dtbdFromUrl", dtbdValue); - continue; } if (param.startsWith(("msisdn="))) { msisdn = param.substring(7); @@ -44,16 +53,39 @@ public void authenticate(AuthenticationFlowContext context) { } if (dtbdValue == null) logger.warn("Client application did not send DTBD"); - if (msisdn == null) logger.info("Client did not speciy MSISDN"); + if (msisdn == null) logger.info("Client did not specify MSISDN"); + + if (allowedMsisdnMethod.equals("URL")) { + if (msisdn != null) { + // Only URL is a valid way to receive MSISDN + // MSISDN found in URL, proceed without displaying form + action(context); + } else { + // No MSISDN in the URL + logger.error("MSISDN only allowed to be received from URL, but request did not contain MSISDN"); + context.failure(AuthenticationFlowError.IDENTITY_PROVIDER_ERROR); + } + return; + } - if (msisdn != null) { - // dont display form, go straight to action() - action(context); - } else { - // Display mobileid form + if (allowedMsisdnMethod.equals("FORM")) { + // MSISDN only allowed to be received from FORM Response response = context.form().createForm("mobileid-form.ftl"); context.challenge(response); + return; } + + if (allowedMsisdnMethod.equals("BOTH")) { + if (msisdn == null) { + // Both methods allowed, but request did not contain MSISDN, display form to get it + Response response = context.form().createForm("mobileid-form.ftl"); + context.challenge(response); + } else { + // URL had MSISDN in it, call MSSP with it + action(context); + } + } + } @Override diff --git a/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticatorFactory.java b/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticatorFactory.java index 52a926b..dc0e5c0 100644 --- a/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticatorFactory.java +++ b/src/main/java/fi/methics/keycloak/laverca/MobileidAuthenticatorFactory.java @@ -10,6 +10,7 @@ import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class MobileidAuthenticatorFactory implements AuthenticatorFactory { @@ -66,6 +67,16 @@ public class MobileidAuthenticatorFactory implements AuthenticatorFactory { property.setHelpText("Keycloak attributes read from user's authentication certificate subject"); configProperties.add(property); } + { + ProviderConfigProperty property = new ProviderConfigProperty(); + property.setName("allowed-msisdn-method"); + property.setLabel("Allowed method of getting MSISDN"); + property.setType(ProviderConfigProperty.LIST_TYPE); + List allowedValues = Arrays.asList("URL", "FORM", "BOTH"); + property.setOptions(allowedValues); + property.setHelpText("Set the allowed method for the authn flow to get MSISDN"); + configProperties.add(property); + } }