]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
Look for SAML username in attributes in addition to subject NameID.
authorRay Lee <ray.lee@lyrasis.org>
Fri, 6 Oct 2023 23:37:28 +0000 (19:37 -0400)
committerRay Lee <ray.lee@lyrasis.org>
Fri, 6 Oct 2023 23:37:28 +0000 (19:37 -0400)
services/common/src/main/java/org/collectionspace/services/common/security/SecurityConfig.java
services/common/src/main/java/org/collectionspace/services/common/security/SecurityUtils.java

index 2283e49a93095d70a56c6a5cb07df85474150ac5..0bfcbead3e79618df904acc61adf536326558b42 100644 (file)
@@ -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<String> 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);
index f4938f782fa05730602058332384fd06011d4d2d..79d1ddb4cb6a3743db4873a400d351d581f2bf80 100644 (file)
@@ -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<String> 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<XMLObject> 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;
+       }
 }