5

I've implemented Single Sign On with Salesforce as Identity Provider scenario using SAML. I want to pass additional attributes via SAML response to the Service Provider. Out of the box the Connected App allows adding custom attributes based on User/Profile/System objects:

enter image description here

I want to add attributes from other objects.

Is it even possible? Should I implement some interface to have specific fields visible?

2
  • Is said business data tied to the specific user who is signing in? I.e. Given the current user as a starting point, how would you identify the additional data of interest. Commented May 29, 2017 at 20:15
  • Isn't adding a custom field on the User sufficient for your use case ?
    – altius_rup
    Commented May 29, 2017 at 23:14

1 Answer 1

10
+50

Looks like you pretty much have covered all the steps an admin can perform to configure salesforce as an Identity provider. He can update the custom attributes to be sent back as part of assertion, but is limited to available dropdown options provided by Salesforce (Mentioned in your question).

However, there is a possible way to extend the custom attribute response using code. Salesforce allows developers to extend the connected app using Custom Connected App Handler. This class needs to extend ConnectedAppPlugin Class to extend the Connect app behavior, as mentioned below:

Contains methods for extending the behavior of a connected app, for example, customizing how a connected app is invoked depending on the protocol used. This class gives you more control over the interaction between Salesforce and your connected app.

Create a class following the below sample code, to populate a map of custom attributes from your business data.

global class ConnectedAppPluginExample extends Auth.ConnectedAppPlugin{

    // Return a user’s permission set assignments
    global override Map<String,String> customAttributes(Id userId, Map<String,String> formulaDefinedAttributes) 
    {  
        //Query Data from your business objects
        List< ObjectName > businessOjbects = [Select [fieldNames] From ObjectName Where [certain conditions]];

        for ( ObjectName businessData :businessOjbects)
        {
            //Just a sample map populated with Unique Name and id
            formulaDefinedAttributes.put(businessData.Name,businessData.id);
        }
        return formulaDefinedAttributes;
    }
}

You can find more details here about the same https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_Auth_ConnectedAppPlugin.htm#apex_class_Auth_ConnectedAppPlugin

Update

Out of curiosity, I tried to implement it by myself (Between two SF orgs) and was able to pass additional SAML attributes as part of response.

This is what I did -

  1. Follow steps listed down in this article to implement SSO between two SF orgs https://developer.salesforce.com/page/Implementing_Single_Sign-On_Across_Multiple_Organizations
  2. Created a sample ConnectedApp handler class and selected it on the Connected App under Custom Connected App Handler section:
global class ConnectedAppPluginExample extends Auth.ConnectedAppPlugin{
    global override Map<String,String> customAttributes(Id userId, Map<String,String> formulaDefinedAttributes) 
    {  
        formulaDefinedAttributes.put('test','test');
        return formulaDefinedAttributes;
    } 
}

Note: There is a catch here. For some reason this class with version >37 is not working. So update its version to 36.

  1. Installed google chrome extension to track SAML assertions. https://chrome.google.com/webstore/detail/saml-chrome-panel/paijfdbeoenhembfhkhllainmocckace
  2. Tested the SSO and verified the SAML response with the custom attribute. Test attribute was present in the SAML response.

Update 2

Morover if you want to use higher API version you have to override customAttributes method like this:

  global override Map<String,String> customAttributes(Id userId, Id 
  connectedAppId, Map<String,String> formulaDefinedAttributes, 
  Auth.InvocationContext context) 
      {  ...

With additional connectedAppId and context attributes.

<saml:Attribute Name="userId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
    <saml:AttributeValue
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">0057F000000dRXp 
    </saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="username" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
    <saml:AttributeValue
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">[email protected]
    </saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
    <saml:AttributeValue
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">[email protected]
    </saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="is_portal_user" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
    <saml:AttributeValue
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">false
    </saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="test" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
    <saml:AttributeValue
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:anyType">test 
    </saml:AttributeValue>
</saml:Attribute>
8
  • Hello @Salesforcesmarty. Thanks for your answer. I've tried that earlier but I haven't noticed any change after applying this custom plugin solution. Moreover I don't know how to add such prepared custom attributes to the SAML response. Do you know any tutorial/example, not only interface implement example, that shows whole solution from start to end? Commented May 30, 2017 at 12:18
  • What do you mean that you don't know how to prepare custom attributes? They are nothing but key values pairs. I don't have any detailed documented examples, but I can guide if you are facing any specific challenges. Commented May 31, 2017 at 0:30
  • Thanks for your help @Salesforcesmarty. There is no problem with preparing custom attributes. The real problem for me is how to pass those parametres to SAML response. Commented May 31, 2017 at 5:47
  • 1
    @MichałKuliński I have verified the connectedApp handler and it is able to pass the additional custom attributes back in response. As part of the POC, I am passing test parameter back to Service Provider. Commented May 31, 2017 at 7:25
  • 2
    OMG. It is API version issue. I've changed API Version to 36 and it works :) Commented May 31, 2017 at 8:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .