I got an opportunity to work on an AEM project, which implements SSO. For SSO implementation in AEM there are many admin level configurations need to be done. In this post I won't be talking about those because there are ample examples available in the internet. In many cases we may need to get the SAML attribute values from the SAML response and then process that for business cases. Here I'll be talking about on how to get those values.
The basic idea of the SSO is to provide access to a secured website from a different website where the user is already logged in. There are many admin related things to be done to implement this. We are not going to talk about how doing that. Here I only talk about from a development perspective. Before that let me talk about the background in a nutshell. Suppose we have two websites 'a.com' and 'b.com'. Both these websites are SSO protected. The user already logged in to the website 'a.com'. Our intention is to access 'b.com' from 'a.com' without asking any credentials. To implement this another path need to be configured which is outside the secure Auth protected path. Suppose that is '/content/b-redirect'. This path should be the url linking from 'a.com' to 'b.com'. Either you can create a servlet for this path or you can directly redirect from there to 'b.com' using any client script.. So when the user clicks the link it'll first go to the '/content/b-redirect' path and from there after applying any logic, it'll be redirected to 'b.com'. Make sure that the '/content/b-redirect' path is not SSO protected. Make sure that the AEM SAML Authentication Handler is configured properly and trust certificate is also placed. After the redirect a SAML request will be redirected to the IDP and it'll be authenticated providing a SAML response. Now we'll be successfully logged in to the 'b.com'.
UserProperties userProps = request.adaptTo(UserProperties.class);
try {
setUserName(userProps.getProperty("userType"));
setFirstName(userProps.getProperty("userRole"));
} catch (RepositoryException e) {
}
However, in certain situations we need to rely on the traditional way of handling SAML response. The limitation of the above approach is that if any configured SAML attribute values become empty then the authentication will fail. In my project I had a situation like when a corporate user logs in they don't have any value for one particular attribute but for other users that has value. This value is significant for our business case as we are using this value as a parameter for a service API call for the non corporate user. So we must have to configure that in the Synchronized Attributes field. In those situation there are two ways to solve.
1) Configure the IDP to pass a default value for empty SAML attribute. By this we can avoid Authentication failure at AEM side. In the code we can implement logic to check the default value. It is easier said than done because any changes done in the IDP may affect many applications. So other applications logic may also need to be changed. In most scenarios this can't be practical.
2) Configure the IDP not to pass empty attribute. This is something more sensible. I can't find any value addition in passing empty value SAML attribute along with the SAML response. If the configured SAML attribute is not available in the response synchronisation won't occur and authentication doesn't fail on AEM side. You may need to convince the business to follow this approach.
Unfortunately, if both these approaches don't work for you then you will be left only to follow the traditional method.