Matthew H
Matthew H

Reputation: 1

How can I receive all roles relating to an Azure application when authenticating with SAML?

I am trying to handle user provisioning in Salesforce. We have decided that we should use a combination of Salesforce JIT (Just-in-time) and Azures provisioning. In order to correctly provision the user I need to send an Auth request to Azure and then Azure returns a payload with various information about that user. Right now it is returning Roles, but it is only returning 1 role.

A user can be in multiple groups that each have different roles in the application. I want to know, is there a way to get Azure to return all the roles a user has in that application after the user has been authenticated?

I have tried looking up documentation but I'm struggling to find something that can point me in the right direction. If you have docs that could help please send them.

Upvotes: 0

Views: 47

Answers (1)

Matthew H
Matthew H

Reputation: 1

I resolved this issue. Long story short, it was the way Salesforce was handling the assertion string in the handleJit method in the JIT Handler class. You need to create a method that will decode the assertion and allow for multi value fields:

private static Map<String, List<String>> parseSAMLResponse(String encodedSamlResponse) {
        String decodedResponse = EncodingUtil.base64Decode(encodedSamlResponse).toString();
        Dom.Document doc = new Dom.Document();
        doc.load(decodedResponse);
        Map<String, List<String>> attributes = new Map<String, List<String>>();
        Dom.XMLNode assertionNode = doc.getRootElement().getChildElement('Assertion', 'urn:oasis:names:tc:SAML:2.0:assertion');
        if (assertionNode != null) {
            Dom.XMLNode attributeStatementNode = assertionNode.getChildElement('AttributeStatement', 'urn:oasis:names:tc:SAML:2.0:assertion');
            if (attributeStatementNode != null) {
                List<Dom.XMLNode> attributeNodes = attributeStatementNode.getChildElements();
                for (Dom.XMLNode attributeNode : attributeNodes) {
                    String attributeName = attributeNode.getAttribute('Name', null);
                    List<Dom.XMLNode> valueNodes = attributeNode.getChildElements();

                    List<String> values = new List<String>();

                    for (Dom.XMLNode valueNode : valueNodes) {
                        if (valueNode.getName() == 'AttributeValue') {
                            values.add(valueNode.getText());
                        }
                    }
                    if (!values.isEmpty()) {
                        attributes.put(attributeName, values);
                    }
                }
            }
        }
        return attributes;
    }

Then make sure to call this and adjust the other methods to take a Map<String, List> or something along those lines, then you can handle multiple roles/groups in the provisioning process :)

Upvotes: -1

Related Questions