Adding Custom Claims to the SAML Response - (How to Write a Custom Claim Handler for WSO2 Identity Server)
Overview
The latest release of WSO2 Identity Server (version 5.0.0), is armed with an "application authentication framework" which provides lot of flexibility in authenticating users from various service providers who are using heterogeneous protocols. It has several extension points, which can be used to cater several customized requirements commonly found in enterprise systems. With this post, I am going to share the details on making use of one such extension point.Functionality to be Extended
When SAML Single Sign On is used in enterprise systems it is through the SAML Response that the relying party get to know whether the user is authenticated or not. At this point relying party is not aware of other attributes of the authenticated user which it may need for business and authorization purposes. To provide these attribute details for the relying party, SAML specification has allowed to send attributes as well in the SAML Response. WSO2 Identity Server supports this out of the box via the GUI provided for administrators. You can refer [1] for the details on this functionality and configuration details.The flexibility provided by this particular extension, comes handy when we have a requirement to add additional attributes to the SAML Response, apart from the attributes available in the underline user store. There may be external data sources we need to look, in order to provide all the attributes requested by the relying parties.
In the sample I am to describe here, we will be looking into a scenario where the system needs to provide some local attributes of the user which are stored in user store, with some additional attributes I expect to be retrieved from an external data source.
Following SAML Response is what we need to send to the relying party from WSO2 IS.
In this response we are having one local attribute, which is role and two additional attributes http://pushpalanka.org/claims/keplerNumber and http://pushpalanka.org/claims/status which have been retrieved from some other method we can define in our extension.
How?
1. Implement the customized logic to get the external claims. There are just two facts we need to note at this effort.
2.Drop the compiled OSGI bundle at IS_HOME/repository/components/dropins. (We developed this as a OSGI bundle as we need to get local claims as well using RealmService. You can find the complete bundle and source code here)
3. Point WSO2 Identity Server to use the new custom implementation we have.
In IS_HOME/repository/conf/security/applicationauthentication.xml configure the new handler name. (in 'ApplicationAuthentication.Extensions.ClaimHandler' element.)
Now if look at the generated SAML Response, we will see the external attributes added.
Cheers!
[1] - https://docs.wso2.com/display/IS500/Adding+a+Service+Provider
- The custom implementation should either implement the interface 'org.wso2.carbon.identity.application.authentication.framework.handler.claims.ClaimHandler' or extend the default implementation of the interface 'org.wso2.carbon.identity.application.authentication.framework.handler.claims.impl.DefaultClaimHandler'.
- The map returned at the method, 'public Map<String, String> handleClaimMappings' should contain all the attributes we want to add to the SAML Response.
Following is the sample code I was written, adhering to the above. The external claims may have been queried from a database, read from a file or using any other mechanism as required.
2.Drop the compiled OSGI bundle at IS_HOME/repository/components/dropins. (We developed this as a OSGI bundle as we need to get local claims as well using RealmService. You can find the complete bundle and source code here)
3. Point WSO2 Identity Server to use the new custom implementation we have.
In IS_HOME/repository/conf/security/applicationauthentication.xml configure the new handler name. (in 'ApplicationAuthentication.Extensions.ClaimHandler' element.)
<ClaimHandler>com.wso2.sample.claim.handler.CustomClaimHandler</ClaimHandler>
Now if look at the generated SAML Response, we will see the external attributes added.
Cheers!
[1] - https://docs.wso2.com/display/IS500/Adding+a+Service+Provider