3

I've implemented Single Sign On with Salesforce as Identity Provider scenario using SAML. To avoid unnecessary data bandwidth I want to pass additional data during Single Sign On login process.

There is a problem, because in Connected App configuration the only custom attributes I can choose are the ones connected with User/Profile/System. I want to get specific business data during SSO process.

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

enter image description here

  • 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. – Daniel Ballinger May 29 '17 at 20:15
  • Isn't adding a custom field on the User sufficient for your use case ? – altius_rup May 29 '17 at 23:14
5
+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.
 < 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">sfsmarty@fsl.com< /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">sfsmarty@yahoo.co.in< /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>

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.

  • 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? – Michał Kuliński May 30 '17 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. – Salesforcesmarty May 31 '17 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. – Michał Kuliński May 31 '17 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. – Salesforcesmarty May 31 '17 at 7:25
  • OMG. It is API version issue. I've changed API Version to 36 and it works :) – Michał Kuliński May 31 '17 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.