function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Holly CoastHolly Coast 

SamlJitHandler won't handle multivalued attributes

I'm trying to get my class that implements Auth.SamlJitHandler to process attributes with multiple values in the SAML assertion. It seems to be saving only one of the values. I notice that the documentation for the Auth.RegistrationHandler interface (for auth providers such as Facebook), which uses an Auth.UserData object, says of the Auth.UserData.attributeMap variable, "Because the map is <String, String>, values that the third party returns that are not strings (like an array of URLs or a map) are converted into an appropriate string representation." However, this doesn't appear to be the case for the attributes variable in SamlJitHandler. Does anybody know of a way to get this to work? It doesn't look like RegistrationHandler can be used for SAML SSO. Thanks!
Jan Aerts 10Jan Aerts 10
I have the same question, so wondering if you found a sollution or workaround for this?

So basically it comes to this:
In the SAML message send to SFDC the attribute has a list of values instead of a single string (see below),

but the createUser and updateUser methods of the samlJitHandler Interface have as parameter attributes a Map<String,String> where the firststring is the name of the attribute from SAML and the second string has the attributeValue (<-> valueS).
So can this somehow work with a list of values or is there a workaround known for this?


<Attribute Name="http://schemas.xmlsoap.org/claims/Group">
<AttributeValue>first_group_user_belongs_to_in AD</AttributeValue>
<AttributeValue>second_group_user_belongs_to_in AD</AttributeValue>
</Attribute>


<Attribute Name="http://schemas.xmlsoap.org/claims/Group1">
<AttributeValue>first_group_user_belongs_to_in AD</AttributeValue>
</Attribute>

<Attribute Name="http://schemas.xmlsoap.org/claims/Group2">
<AttributeValue>second_group_user_belongs_to_in AD</AttributeValue>
</Attribute>





 
Holly CoastHolly Coast
Hi Jan, I did not find a solution or workaround for the issue of handling multi-valued attributes that are sent on the SAML assertion. I do know that if a series of attribute values ARE sent (from SAML) in a comma-separated string, that works fine and you can parse that string to get the individual values. But in my case, the attribute values are sent like your first example above (single attribute element, with multiple AttributeValue subelements). I talked with our team that manages our SAML attribute release configs about possibly writing special code for this one multi-valued attribute that I need to retrieve, but as it turns out our university is starting on a new Identity Management project so we decided to table my little project that would need these values until that IM effort is complete and perhaps I will get my data in another way.

I would be interested if anybody else has more info on this, though - it would be nice if the SamlJitHandler could work more like the RegistrationHandler and convert those multi-valued attributes to comma-separated strings.

By the way, I have a coworker in IT here at Northern Arizona University in Flagstaff with the same last name as yours ... any relation? I'd never heard the name before meeting her. 
Sam Sharma 16Sam Sharma 16
Hi @Holly Coast, I have the same problem with JIT handler as it cannot read multivalued attributes. Please let me know how to handle that?
Hardik Ranjan127Hardik Ranjan127

Hello @Holly Coast ,

To get miltiple attributes we need to extract that from assertion and encode them to xml and then get values from xml attribute.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Following:-



Method:- 

private void handleJit(boolean create, User u, Id samlSsoProviderId, Id communityId, Id portalId, String federationIdentifier,
                           Map<String, String> attributes, String assertion) {
 


Calling the XML extractor method:-

 // Encode Base 64 Decode assertion value for getting saml
  Blob blobXML = EncodingUtil.base64Decode(assertion);

List<String> application_access_grp = getSAML(blobXML.toString(), 'ApplicationAccessGroups'); // method defined below

 

 

XML Value Extractor:-

 //Get Attribute values from SAML String
    public static List<String> getSAML(String xmlString, String attributeValue) {
        List<String> listOfAssertionValues = new List<String>();
       
        String ns = 'urn:oasis:names:tc:SAML:2.0:assertion';
       
        Dom.document doc = new Dom.Document();    
        doc.load(xmlString);
        dom.XmlNode xroot = doc.getrootelement();
       
       
        List<dom.XmlNode> xnAttributeList = xroot.getChildElement('Assertion', ns).getChildElement('AttributeStatement',ns).getChildElements();        
       
        List<DOM.XmlNode> xnAttributeValList = new List<DOM.XmlNode>();
        for(Dom.XmlNode xn : xnAttributeList){
           
            //Check Name attibute matches the one you want
            System.debug('xn: ' + xn);
           
            if(xn.getAttribute('Name','') == attributeValue){
                xnAttributeValList = xn.getChildElements();
                for(Dom.XmlNode xnv : xnAttributeValList){
                    listOfAssertionValues.addAll(xnv.getText().split(','));
                }
            }
        }
       
        return listOfAssertionValues;    
    }

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Result:- application_access_grp list will have the values of that attribute.  -> 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Alex Schach 11Alex Schach 11
@Hardik Ranjan127 THANK YOU! Your solution worked perfectly. The "xn.getAttribute('Name')" is what I had been missing.