Use Case:
Integrate it with Custom Pluggable Login Module (AEM 6)
Step1 : create pluggable login Module
Step2 : Plug it in your custom auth handler
Example: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/
Example of Open Source Extended Authentication Handler:
- You want to use custom Authentication handler instead of OOTB one for authentication.
- Custom User Registration
- http://sling.apache.org/site/authentication.html
- http://sling.apache.org/site/authentication-authenticationhandler.html
- http://sling.apache.org/apidocs/sling6/org/apache/sling/auth/core/spi/AuthenticationHandler.html
Available Authentication Handler in CQ:
1) Create custom class extending Sling Authentication Handler and override available methods
2) Create a form (Your custom Login form)
which will be something like this
String action = currentPage.getPath() +"/j_mycustom_security_check";
<form method="POST" action="<%= xssAPI.getValidHref(action) %>">
Enter User Name: <input name="j_username" type="text" />
Enter Passord: <input name="j_password" type="text" />
<input type="button" name="Click Here to login">
</form>
You can also use Ajax post or something to see if response is 200 (Which mean successful login)
3) Then under apache sling post servlet, Make sure that you allow parameter you are posting. In this case j_*
4) Add your custom authentication prefix to sling authenticator service
5) Once you have your bundle deployed, You should see your additional authentication handler.
Integrate it with Custom Pluggable Login Module (AEM 6)
Step1 : create pluggable login Module
Step2 : Plug it in your custom auth handler
Example: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/
Example of Open Source Extended Authentication Handler:
CQ OOTB Extended authentication Handler
Day CRX Sling - Token Authenticationcom.day.crx.sling.crx-auth-token)Adobe Granite SSO Authentication Handlercom.adobe.granite.auth.sso)Day Communique 5 PIN Authentication Handlercom.day.cq.cq-pinauthhandler
There are a lot of things needed for creating your custom user registration process (You might / Might not) Need following,
1) Custom Login Module http://www.wemblog.com/2012/06/how-to-add-custom-login-module-in-cq55.html to sync users / group in CQ from third party system
2) Custom Authentication handler as above
3) Reverse replication to sync user across (If user registration is in publish)
Note: Above code is just Pseudo code. Please test, You might have to add your custom logic for this to work.
Let me know if you have any question or comment.
Hi Yogesh,
ReplyDeleteI really like this article and this blog, so thank you for putting this information together and taking the time to maintain and update this blog. I just wanted to call out one point I noticed:
"And more ..... If you can decompile these bundle, You should be able to see example of how it is implemented."
If a client decompiles an OOTB proprietary jar, then technically they're in violation of their license agreement and could lose support and/or license. As such, I would really not suggest decompiling the jars, even if they are good examples.
That being said, again I really do like this blog and appreciate the effort.
Doug,
DeleteThank you very much for your comment. When I said decompiled, I meant Open source (Sling) authentication handler (Including form based). But I can see confusion here. Thus deleted that portion.
Again thanks for review.
Yogesh
Hi Yogesh,
ReplyDeleteThis post is what I was looking for. I am bit confused about some of the parameters and methods you have defined in the code though. Constant ATTR_HOST_NAME_FROM_REQUEST is not defined. Is it same to assume it as "hostname"?
Regards,
Anup
Anup,
DeleteYou do not need that variable. This is just an example of how you can set custom attribute in credential object
Yogesh
Can we have a sample package to get into the details?
ReplyDeleteHello,
DeleteSample Package is difficult in this case because each custom authentication requirement is different. Let me know if you have any specific question.
Yogesh
Hello Yogesh,
ReplyDeleteGreat article. If I were to create a Custom authentication module, which uses a simple CSV file for User name and Password, can I still use the OOTB login page ? I dont want users to Register and I prefer the CSV approach as it is just the list of users who I want to control access for a very short period of time.
Silican,
DeleteYou do not need custom authentication handler to create user and group. You can use Java API to parse CSV and then Jackrabbit API to create user. Here is example of creating user and group in CQ http://wemcode.wemblog.com/user-group-management. That site also have example of how you can create Role.
Yogesh
Hi Yogesh,
ReplyDeleteThank you for the above tips. I have implemented something similar in order to do some additional checks on the user who is authenticating (e.g. check their account has not expired).
Do you know how I might then call the default AuthenticationHandler from my extractCredentials? In other words, revert to the normal "j_security_check" ? I am trying to call the default handler's extractCredentials() and return the AuthenticationInfo object if my own handler is satisfied with it's additional checks. Any ideas?
John,
DeleteYou can just return null from custom authentication handler and then next authentication handler will pick up.
Yogesh
Thanks Yogesh, I guess what I am asking is after I have authenticated in my custom AuthenticationHandler and return AuthenticationInfo, how do I then get CQ to create the logged in session cookie? When I return the AuthenticationInfo , it fires the authenticationSucceeded, but there is no session cookie created.
DeleteI ended up using com.day.crx.security.token.TokenUtil.createCredentials() in my authenticationSucceeded() to create the token, just in case anybody is trying to do something similar.
DeleteThank you John Sharing this. This will work if Order of Token Auth Handler comes after your custom Auth handler.
DeleteYogesh
Thanks Yogesh,
ReplyDeleteif I return null from my custom handler, wouldn't this mean that my custom conditions are not included? I want to include my conditions PLUS the default conditions handled by j_security_ check..
I have question related to same custom login approach that you have suggested. Say I want to authenticate user against DataBase, Say I do that in authenticationSucceeded and it returns true for the first time. So the Question is how do you maintain a session then? like how would you ensure access to your secure area is being authenticated against logged in user each time.
ReplyDeleteApologies but I am little unaware of the login token purpose. Also I dont want to maintain users in CQ Repository what to do then, how their access to repository pages will be handled?
I have question related to Auto login in CQ5.6. I have created registration form for registring new user in my site. I am using a custom post servlet for creating users.
ReplyDeleteI want my users to get logged in once they have completed registration process.
How can we make user logged in automatically once registration process is completed?
Ankur,
DeleteTry something like
TokenUtil.createCredentials(request, response, slingRepository, userID, true) in your servlet service method.
Maven dependency for TokenUtil:
com.day.crx.sling
crx-auth-token
2.4.23
provided
Also this could be useful for your use case:
http://www.cqcon.eu/content/dam/cqcon/Pr%C3%A4sentation_Antonio_Sanso.pdf
Please confrim that this works for you.
I tried to follow the above steps to implement the Custom Authentication handler but was stuck at some point.
ReplyDelete1. When I implemented using the component properies "@Property(name = AuthenticationHandler.PATH_PROPERTY, value = "/")," I was not able to reach to the Custom Authentication Handler. But when I used "@Property(name = AuthenticationHandler.PATH_PROPERTY, value = "/content")" . What is the correct way to do so?
2. Even if I reach the authenticationSucceeded() function I am obtaining a 403 Forbidden from the "j_mycustom_security_check" handler. Has anyone faced similar problem?
3. What does the value "static final String AUTH_TYPE" symbolizes.
Thanks for helping in advance.
Just to add I am using CQ5.6.1 and version of jar for org.apache.sling.auth.core is 1.1.6
Delete@HK, did you get any resolution to 403 error? I am facing the same issue
DeleteHi Yogesh,
ReplyDeleteI am trying to authenticate from open am , In request cookie value is available once user get authenticate from open am , We provide the filter in dispatcher like /content/mysite*. How we can aunthenticate in cq5. When we access from openam the dispatcher url it show us a prompt "Your request could not be completed becauseyou have signed out".Please let me know how to go around
Hello Raj,
DeleteUsually you get that error when there is some exception in login process. Can you check your error log and make sure that nothing is wrong ?
Yogesh
Hi Yogesh,
ReplyDeleteI am working out with LDAP Authentication, I created a login component which sends a request to your_path/j_security_check. with username and password and the user is authenticated against the LdapLoginModule i believe which is good.
Now, if the user is authenticated i want to check whether they are authorized to use the system or not. There is a property on user profile node with which we check that.
The problem is once i make a request to path/j_security_check it automatically logs in the user to the system. I wan to avoid that before i know if the user is authorized to use the system or not.
Can you please let me know how can i just override the authorization mechanism.
Just in case somebody is interested, i have got this working using form Authentication handler http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
DeleteI almost ended up using most parts of this handler as i wanted to avoid writing any security code because it might just have flaws.
Since i kept my handler service ranking to be 0 and Token Authentication handler rank was higher, i ended up creating com.day.crx.security.token.TokenUtil.createCredentials() in the authenticationSucceeded method. If you happen to have custom Authentications before you login the user you can do it in authenticationSucceeded method as well.
Note in case your form has got a resource for redirection in form of an input hidden field i saw a weird behavior where even with valid creds i was seeing INVALID_CREDNETIALS error but as soon i put a call to TokenAuth the login redirection started working.
Sam,
DeleteThank a lot of sharing your problem and solution in Blog. Really appreciated.
Yogesh
Hi Yogesh,
ReplyDeleteI am working with LDAP Authentication, Siteminder authenticates the user with credentials from LDAP and sends user data to response.
So I want to store that user data in session bean so that I can add more details specific to that user in that bean.
For it I created a user bean in my top header component jsp which is in every page.
And I am trying to make the page "session=true" it sends "500: Internal Server error".
Can you please help
You can simply use request.getRemoteuser() right ? Not sure why you need to store this in session. Note that session is not scalable in case you are planning to use caching in future.
DeleteHi Yogesh,
ReplyDeleteI built my authentication handler by following your instructions and the sample code, https://github.com/davidjgonzalez/com.activecq.samples/blob/master/core/src/main/java/com/activecq/samples/slingauthenticationhandler/impl/TokenSlingAuthenticationHandler.java.
in the method "authenticationSucceeded", I call "return false" to continue the framework. however, I see an error is reported in the error.log: org.apache.sling.auth.core.impl.SlingAuthenticator handleSecurity: AuthenticationHandler did not block request; access denied
did I miss any configurations?
could you please help?
Hi, I have imported org.apache.sling.auth.core.AuthUtil in the java class. But this is showing an error.
ReplyDeleteKindly help.
This comment has been removed by the author.
DeleteIn addition to the above comment
ReplyDeletehttp://sling.apache.org/apidocs/sling5/org/apache/sling/jcr/resource/JcrResourceConstants.html package dos't contains "JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS"
Hello Renju,
DeleteThanks for your Feedback. I updated document, also added how you can create your pluggable login module.
Yogesh
is it possible to call the j_security_check from my own servlet? instead of from action
ReplyDeleteHello Fabian,
DeleteWhat is the use case for this ? You might be able to achieve your use case using some other method.
Yogesh
Hi Yogesh,
ReplyDeleteI tried to follow the above steps to implement the Custom Authentication handler in CQ5.5 but was stuck at some point. I did configuration mentioned in above but Custom Authentication handler is not getting invoke. I got below warning:
“org.apache.sling.auth.core.impl.SlingAuthenticator handleSecurity: AuthenticationHandler did not block request; access denied”.
Can u help, will it require any other configuration and how to resolve it.
Same here (AEM 5.6.1)!
DeleteHi Yogesh,
ReplyDeleteGreat article. I have one question here - Do we not need to create a login-tokrn cookie in the authenticationSucceeded method before sending the response as true? Otherwise how would the further requests be authenticated?
Hello Karttik,
DeleteNot in this case. You can have such mechanism to avoid call to server (Chose any cookie you want). In this case all request will go through authentication handler.
Yogesh