Expand my Community achievements bar.

Custom Authentication Handler not handling invalid login-token properly

Avatar

Level 2

I have a similar issue to this one just slightly different.

 

We have a custom Authentication Handler that implements AuthenticationHandler.  In the extractCredentials method, the first thing that happens is a check for an existing login-token.  If it exists, the method returns null to bypass the rest of the authentication code.

The issue we are running into is when the login-token exists but is no longer valid, the user receives a 403 error.

How can we check for existing AND VALID login-token?

Also where can I see the OOTB SamlAuthenticationHandler code?  It sounds like there may be a working example of this case in that code.

5 Replies

Avatar

Level 9

Hi @laniweisbart ,

 

I read contract of org.apache.sling.auth.core.spi.AuthenticationHandler#extractCredentials.

/**
* Extracts credential data from the request if at all contained.
* <p>
* The method returns any of the following values :
* <table>
* <caption>Extracted Information</caption>
* <tr>
* <th>value
* <th>description
* </tr>
* <tr>
* <td><code>null</code>
* <td>no user details were contained in the request or the handler is not
* capable or willing to extract credentials from the request
* </tr>
* <tr>
* <td>{@link AuthenticationInfo#DOING_AUTH}
* <td>the handler is in an ongoing authentication transaction with the
* client. Request processing should be aborted at this stage.
* </tr>
* <tr>
* <td>{@link AuthenticationInfo#FAIL_AUTH}
* <td>the handler failed extracting the credentials from the request for
* any reason. An example of this result is that credentials are present in
* the request but they could not be validated and thus not be used for
* request processing. When returning this value, the authentication handler
* may also set the {@link #FAILURE_REASON} request attribute to inform
* interested parties (including its own
* {@link #requestCredentials(HttpServletRequest, HttpServletResponse)}
* method for the reasons of failure to extract the credentials.
* </tr>
* <tr>
* <td><code>AuthenticationInfo</code> object
* <td>The user sent credentials. The returned object contains the
* credentials as well as the type of authentication transmission employed.
* </tr>
* </table>
* <p>
* The method must not request credential information from the client, if
* they are not found in the request.
* <p>
* The value of {@link #PATH_PROPERTY} service registration property value
* triggering this call is available as the <code>path</code> request
* attribute. If the service is registered with multiple path values, the
* value of the <code>path</code> request attribute may be used to implement
* specific handling.
*
* @param request The request object containing the information for the
* authentication.
* @param response The response object which may be used to send the
* information on the request failure to the user.
* @return A valid <code>AuthenticationInfo</code> instance identifying the
* request user, {@link AuthenticationInfo#DOING_AUTH} if the
* handler is in an authentication transaction with the client or
* null if the request does not contain authentication information.
* In case of {@link AuthenticationInfo#DOING_AUTH}, the method must
* have sent a response indicating that fact to the client.
*/

It says that you need to return null if the request doesn't contain authentication information. However, you mentioned that you return null when login-token is present. So, you implemented this handler not according to contract. In your case, you need to return org.apache.sling.auth.core.spi.AuthenticationInfo#DOING_AUTH. 

 

In case if you want to investigate SAML implementation, you can find com.adobe.granite.auth.saml.SamlAuthenticationHandler in the com.adobe.granite.auth.saml bundle. You can import bundle to Intellij and debug classes inside.

 

Best regards,

Kostiantyn Diachenko.

Avatar

Administrator

@arunpatidar @Rohan_Garg @sarav_prakash @anupampat @martin_ecx_io @stiegjo22 @Tad_Reeves @Ravi_Pampana @PcProf Would love to get your perspective on this question. Please take a look if you can!



Kautuk Sahni

Avatar

Community Advisor

Avatar

Level 5

@laniweisbart I saw you are referring to my post and possible solution is.

 

If client has a login-token which is valid 12 hours from now and the client makes request after 12 hours then it is clearly a invalid token and the request will still be having login-token cookie but invalid one. In this case for each and every request you need to validate the login-token value. This can be done by 2 ways.

1. Enable refresh tokens. Means, if token is valid for 10Min then refresh token will be issued at 5th minute if you use AEM in between 0 to 9.59 minutes. 

2. In extractCredentials method put a check for incoming request has a valid login-token. First you need to decode the login-token and then you will get actual token value stored in AEM user. Now get the user and user path and then get the actual token node and see the expiry property and compare. This is a costly operation.

3. Debug OOTB APIs which will tell you validity of login-token. com.day.crx.security.token package

4. The simplest way is inside extractCredentials method call a simple AEM servlet which just gives 200 response back. If the request has valid login token then you will get 200 response and if request has invalid token then you may get 401 then you can assume request has invalid token. Now we need to remove the cookie from the request so that it will redirect to default auth handler and you will be challenged to authenticate.

 

For SAML authentication handler, get the jar file of samlAuthHandler. See the PID of saml config and then get the jar file using package path. You may get .class file in the jar so you need to convert to .java file.

 

Note: Please do mention members in the replies so that they will get notifications.

 

Thanks

Ramesh

Avatar

Level 2

Thank you for these ideas.  I'm still not sure how to check the validity of the login-token but I am going to see if I can use the 

com.day.crx.security.token.TokenCookie 

class per your suggestion.