Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

AuthenticationInfoPostProcessor for saml SSO

Avatar

Level 4

Has anyone tried to do a  implementation of AuthenticationInfoPostProcessor for the saml authentication. I have configured out-of-the-box SAML Granite Authentication Handler.  I need to do a post processing once the saml authentication is successful.

In my post processor implementation, I cannot get the user name from AuthInfo.

My pseudo code - (The statement on line# 21 is never reached. )

@Component(label = "Custom Authentication Post Processor", description = "Custom Authentication Post Processor for blah blah blah", immediate = true, metatype = true) @Service public class CustomAuthenticationInfoPostProcessor implements AuthenticationInfoPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(CustomAuthenticationInfoPostProcessor.class); @Override public void postProcess(AuthenticationInfo info, HttpServletRequest request, HttpServletResponse response) throws LoginException { if(info == null ) { LOGGER.debug("AuthenticationInfo is null. " + "Skip post processing this request."); return; } if(info.getUser() == null ) { LOGGER.debug("User is null. " + "Skip post processing this request."); return; } LOGGER.info("user is  ===================> " + info.getUser()); } }

Any pointers on how to retrieve user name or user id from here ?

As an alternative, how do I get the original saml request to retrieve user details from there ?

 

/Regards
Kanwal

1 Accepted Solution

Avatar

Correct answer by
Level 4

I finally got it to work !. Needed to get the Usermanager from ResourceResolver and Session by help of  AuthenticationInfo enlightened

 

 

@Component(    label = "Custom Authentication Post Processor", description = "Custom Authentication Post Processor for blah blah blah", immediate = true, metatype = true) @Service public class CustomAuthenticationInfoPostProcessor implements AuthenticationInfoPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(CustomAuthenticationInfoPostProcessor.class); @Reference private ResourceResolverFactory resourceResolverFactory; /** * Sling Cryptographic support: Used to encrypt the SAML response message in the repository */ @Reference private CryptoSupport cryptoSupport; @Reference ConfigurationAdmin configAdmin; @Override public void postProcess(AuthenticationInfo info, HttpServletRequest request, HttpServletResponse response) throws LoginException { if(!request.getPathInfo().startsWith("/editor.html/content/")){ return; } ResourceResolver resourceResolver = null; Session session = null; UserManager userManager = null; Authorizable auth = null; Value[] samlResponeProperty = null; String samlResponseString = null; try { resourceResolver = resourceResolverFactory.getResourceResolver(info); session = resourceResolver.adaptTo(Session.class); userManager = resourceResolver.adaptTo(UserManager.class); auth = userManager.getAuthorizable(session.getUserID()); samlResponeProperty = auth.getProperty("samlResponse"); samlResponseString = cryptoSupport.unprotect(samlResponeProperty[0].getString()); LOGGER.debug("user is  ===================> " + info.getUser()); } catch (Exception e) { e.printStackTrace(); LOGGER.debug(e.getMessage()); } LOGGER.info("user is  ===================> " + info.getUser()); } }

Thanks you so much you guys yes  @Justin , @Lokesh, @Miroslav

 

/Regards
Kanwal

View solution in original post

11 Replies

Avatar

Level 10

Hi Kanwal,

Refer [1] for custom implementation of AuthenticationInfoPostProcessor. But however, we need to check what would AuthenticationInfo would have after SAML authentication

[1] https://github.com/englishtown/sling-auth-crowd/blob/master/src/main/java/org/apache/sling/auth/crow...

Avatar

Employee

When using the SAML Authentication Handler (or in fact any Authentication Handler which creates tokens), the AuthenticationInfo object will only ever contain the authentication token.

I'm guessing when you say "the original saml request" you actually mean "the original saml response" :) This is stored as a property named samlResponse on the user node. It is encrypted, so you need to pass the value through CryptoSupport.unprotect()[1]

Regards,

Justin

[1] https://docs.adobe.com/docs/en/aem/6-0/develop/ref/javadoc/com/adobe/granite/crypto/CryptoSupport.ht...)

Avatar

Level 1

justin_at_adobe wrote...

When using the SAML Authentication Handler (or in fact any Authentication Handler which creates tokens), the AuthenticationInfo object will only ever contain the authentication token.

 

Util function TokenUtil#createCredentials used in SAML auth handler, should set both user id and token credentials. Maybe authentication was not successful and SAML authentication handler returned AuthenticationInfo.FAIL_AUTH? In that case line 21 also would not be reached. Setting log level for "com.adobe.granite.auth.saml" to DEBUG can reveal more info.

Avatar

Level 4

justin_at_adobe wrote...

When using the SAML Authentication Handler (or in fact any Authentication Handler which creates tokens), the AuthenticationInfo object will only ever contain the authentication token.

I'm guessing when you say "the original saml request" you actually mean "the original saml response" :) This is stored as a property named samlResponse on the user node. It is encrypted, so you need to pass the value through CryptoSupport.unprotect()[1]

 

@Justin

How do I retrieve the node property using this token.I m able to see that samlResponse property is there but I would still need the user id or some reference to that user to be able to retrieve that particular user's property.

The only attributes that are there in TocenCredentials are -

  • .token.useragent=Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
  • .token.ip=0:0:0:0:0:0:0:1

@Lokesh, Thanks for the reference, but for any custom authentication handler that I wrote, I can see the user's details in AuthenticationInfo object and this is what the code you mention is doing as well. But, when it comes to saml authentication handler ootb in AEM, the this object just has the token only. 

@Miroslav, I enabled the debug for the package "com.adobe.granite.auth.saml" but I am not seeing any exceptions of any kind.

 

/Regards
Kanwal

Avatar

Level 1
 

@Miroslav, I enabled the debug for the package "com.adobe.granite.auth.saml" but I am not seeing any exceptions of any kind.

Hi Kanwal, before line 

if(info.getUser() == null ) { ...

can you output debug message with "info.getAuthType()"? Also can you check what is the version of the bundle crx-auth-token?

Avatar

Level 4

I added the following statement - LOGGER.debug( "Request path - "+ request.getPathInfo() +  " & info.getAuthType() - "+ info.getAuthType());

For info.getAuthType(), the log always prints 'TOKEN' I am attaching the log file.

 

Is this the information you are after ?

Label - Adobe Granite Token Authentication
Symbolic Name    - com.day.crx.sling.crx-auth-token
Version    - 2.5.20.CQ610-B0002
Bundle Location    - launchpad:resources/install/0/crx-auth-token-2.5.20-CQ610-B0002.jar

 

/Regards
Kanwal

Avatar

Level 10

I think, authenticationInfo.getUser() will only hold the user if the user has been set in the map and in the SAML authentication it wouldnt anyways. So I am doubtful If we can get the User details as it would be encrypted. 

However, you can log a support ticket if they have any say on this !

Avatar

Correct answer by
Level 4

I finally got it to work !. Needed to get the Usermanager from ResourceResolver and Session by help of  AuthenticationInfo enlightened

 

 

@Component(    label = "Custom Authentication Post Processor", description = "Custom Authentication Post Processor for blah blah blah", immediate = true, metatype = true) @Service public class CustomAuthenticationInfoPostProcessor implements AuthenticationInfoPostProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(CustomAuthenticationInfoPostProcessor.class); @Reference private ResourceResolverFactory resourceResolverFactory; /** * Sling Cryptographic support: Used to encrypt the SAML response message in the repository */ @Reference private CryptoSupport cryptoSupport; @Reference ConfigurationAdmin configAdmin; @Override public void postProcess(AuthenticationInfo info, HttpServletRequest request, HttpServletResponse response) throws LoginException { if(!request.getPathInfo().startsWith("/editor.html/content/")){ return; } ResourceResolver resourceResolver = null; Session session = null; UserManager userManager = null; Authorizable auth = null; Value[] samlResponeProperty = null; String samlResponseString = null; try { resourceResolver = resourceResolverFactory.getResourceResolver(info); session = resourceResolver.adaptTo(Session.class); userManager = resourceResolver.adaptTo(UserManager.class); auth = userManager.getAuthorizable(session.getUserID()); samlResponeProperty = auth.getProperty("samlResponse"); samlResponseString = cryptoSupport.unprotect(samlResponeProperty[0].getString()); LOGGER.debug("user is  ===================> " + info.getUser()); } catch (Exception e) { e.printStackTrace(); LOGGER.debug(e.getMessage()); } LOGGER.info("user is  ===================> " + info.getUser()); } }

Thanks you so much you guys yes  @Justin , @Lokesh, @Miroslav

 

/Regards
Kanwal

Avatar

Level 10

This is great !! Thanks for finding...

Avatar

Level 4

Hi Kanwaljit,

Is there any way to get SAML response from request, read it to get data instead of decrypting samlResponse property from user node after successful login?

Referred this blog http://apoorva-ganapathy.blogspot.com/2016/08/aem-processing-saml-response-using.html but both httpRequest.getPathInfo() and httpRequest.getParameter("saml_login") are null in custom AuthenticationInfoPostProcessor.

Any help on how can we read SAML response in custom AuthenticationInfoPostProcessor in AEM 6.4?

Thanks & Regards,

Srikanth Pogula.

Avatar

Level 2

Hi Srikanth,

 

I understand this was long back but did you get the route cause for the null values from httpRequest.getPathInfo() and httpRequest.getParameter("saml_login")