From a4df68259a7fdf7aeac6784f6970aa6a295819a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20D=C3=A9nari=C3=A9?= Date: Mon, 29 Jan 2024 14:08:57 +0100 Subject: [PATCH] feat: [SAML] Allow to identify user by email - meeds-io/meeds#1615 - EXO-69432 Before this fix, SAML authentication require username as subject in the SAML assertion response. As for the login (in which we are able to log with username or email), we would propose to have the email as subject of the assertion. --- .../valve/AbstractSPFormAuthenticator.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sso-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java b/sso-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java index c177f8ceb..4d302e027 100644 --- a/sso-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java +++ b/sso-saml-plugin/src/main/java/org/gatein/sso/saml/plugin/valve/AbstractSPFormAuthenticator.java @@ -23,6 +23,10 @@ import org.apache.catalina.connector.Response; import org.apache.catalina.realm.GenericPrincipal; import org.apache.tomcat.util.descriptor.web.LoginConfig; +import org.exoplatform.commons.utils.ListAccess; +import org.exoplatform.services.organization.Query; +import org.exoplatform.services.organization.User; +import org.exoplatform.services.organization.UserHandler; import org.picketlink.common.ErrorCodes; import org.picketlink.common.constants.GeneralConstants; import org.picketlink.common.constants.JBossSAMLConstants; @@ -584,6 +588,8 @@ private boolean handleSAML2Response(Request request, Response response, LoginCon String username = principal.getName(); String password = ServiceProviderSAMLContext.EMPTY_PASSWORD; + username = checkForEmail(username); + roles.addAll(extractGateinRoles(username)); if (logger.isTraceEnabled()) { logger.trace("Roles determined for username=" + username + "=" + Arrays.toString(roles.toArray())); @@ -655,6 +661,8 @@ private boolean handleSAML2Response(Request request, Response response, LoginCon return localAuthentication(request, response, loginConfig); } + + private String getSAMLVersion(Request request) { String samlResponse = request.getParameter(GeneralConstants.SAML_RESPONSE_KEY); String version; @@ -850,4 +858,27 @@ private boolean isAjaxRequest(Request request) { String requestedWithHeader = request.getHeader(GeneralConstants.HTTP_HEADER_X_REQUESTED_WITH); return requestedWithHeader != null && "XMLHttpRequest".equalsIgnoreCase(requestedWithHeader); } + + private String checkForEmail(String username) { + //allow to use email as identifier in SAML assertion + //if username is an email, we read the related user, and return his username, if there is only one result with this email + try { + if (username.contains("@")) { + OrganizationService organizationService = PortalContainer.getInstance().getComponentInstanceOfType(OrganizationService.class); + UserHandler userHandler = organizationService.getUserHandler(); + Query emailQuery = new Query(); + emailQuery.setEmail(username); + ListAccess users; + users = userHandler.findUsersByQuery(emailQuery); + if (users != null && users.getSize() == 1) { + return users.load(0, 1)[0].getUserName(); + } + } + } catch (Exception e) { + logger.samlSPHandleRequestError(e); + return null; + } + return username; + } + }