From 740dc809b6fcb1b331b29626821346ba212076cf Mon Sep 17 00:00:00 2001 From: Ray Lee Date: Fri, 6 Oct 2023 19:37:28 -0400 Subject: [PATCH] Look for SAML username in attributes in addition to subject NameID. --- .../common/security/SecurityConfig.java | 8 ++- .../common/security/SecurityUtils.java | 52 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityConfig.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityConfig.java index 2283e49a9..0bfcbead3 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityConfig.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityConfig.java @@ -146,6 +146,12 @@ import com.nimbusds.jose.proc.SecurityContext; public class SecurityConfig { private final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); + public static final List EMAIL_ATTR_NAMES = Arrays.asList( + "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", + "email", + "mail" + ); + public static final String LOGIN_FORM_URL = "/login"; public static final String LOGOUT_FORM_URL = "/logout"; @@ -537,7 +543,7 @@ public class SecurityConfig { .convert(responseToken); Assertion assertion = responseToken.getResponse().getAssertions().get(0); - String username = assertion.getSubject().getNameID().getValue(); + String username = SecurityUtils.getSamlAssertionUsername(assertion, EMAIL_ATTR_NAMES); try { CSpaceUser user = (CSpaceUser) userDetailsService.loadUserByUsername(username); diff --git a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java index f4938f782..79d1ddb4c 100644 --- a/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java @@ -51,6 +51,11 @@ import org.jboss.crypto.digest.DigestCallback; import org.jboss.resteasy.spi.HttpRequest; import org.jboss.security.Base64Encoder; import org.jboss.security.Base64Utils; +import org.opensaml.core.xml.XMLObject; +import org.opensaml.core.xml.schema.XSString; +import org.opensaml.saml.saml2.core.Assertion; +import org.opensaml.saml.saml2.core.Attribute; +import org.opensaml.saml.saml2.core.AttributeStatement; /** * @@ -319,4 +324,51 @@ public class SecurityUtils { return result; } + + /* + * Retrieve the CSpace username from a SAML assertion. If the assertion's subject nameID is an + * email address, it is returned. Otherwise, the first value of the given attribute name is + * returned. + */ + public static String getSamlAssertionUsername(Assertion assertion, List attributeNames) { + String subjectNameID = assertion.getSubject().getNameID().getValue(); + + if (subjectNameID.contains("@")) { + return subjectNameID; + } + + for (String attributeName : attributeNames) { + String value = findSamlAssertionAttribute(assertion, attributeName); + + if (value != null) { + return value; + } + } + + return null; + } + + private static String findSamlAssertionAttribute(Assertion assertion, String attributeName) { + for (AttributeStatement statement : assertion.getAttributeStatements()) { + for (Attribute attribute : statement.getAttributes()) { + String name = attribute.getName(); + + if (name.equals(attributeName)) { + List attributeValues = attribute.getAttributeValues(); + + if (attributeValues != null && attributeValues.size() > 0) { + XMLObject value = attributeValues.get(0); + + if (value instanceof XSString) { + XSString stringValue = (XSString) value; + + return stringValue.getValue(); + } + } + } + } + } + + return null; + } } -- 2.47.3