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 -
- 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
- 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.
- Installed google chrome extension to track SAML assertions.
https://chrome.google.com/webstore/detail/saml-chrome-panel/paijfdbeoenhembfhkhllainmocckace
- 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>