13 Replies Latest reply on Apr 8, 2011 1:07 AM by macois

    How to write login module?

    Marc Boorshtein Newbie

      I'm trying to write a login module for GateIn 3.1.  Looking at the documentation for how sso systems are implemented I don't see how the various SSO systems are integrated (ie where does CAS or OpenSSO validate its session?).  I downloaded the source but org.gatein.sso.agent.login.SSOLoginModule isn't there.


      Any help would be appreciated




        • 1. How to write login module?
          Prabhat Jha Master

          You can see the SSO code at http://anonsvn.jboss.org/repos/gatein/components/sso/ If you want to get an idea of customizing just the login you can see the details at http://community.jboss.org/docs/DOC-16503

          • 2. How to write login module?
            Marc Boorshtein Newbie

            Thanks, but what I still don't understand is the relationship between SSOLoginModule, a JAAS login module and GenericSSOAgent which is a servlet.  Any help you could give me would be greatly appreciated.  I'm trying to write a login module for a reverse proxy based sso system.




            • 3. How to write login module?
              Marek Posolda Expert

              GenericSSOAgent servlet is called after authentication on SSO server. This agent is doing validation of SSO ticket (it delegates processing to CASAgent, JossoAgent or OpenSSOAgent according to used SSO framework) and it obtain username from SSO ticket. This username is then stored into TokenStore service.


              SSOLoginModule is not doing any real authentication because this was already happen on SSO server side. So it only read username from TokenStore (saved in previous step by GenericSSOAgent) and do some initialization steps for performing login of user inside GateIn portal. Last login module JbossLoginModule is adding JAAS roles of user according to his GateIn roles.


              So that's how it works in shortcut. It can be definitely good for you to look at sources of existing login modules and other code used for authentication to have deeper understanding. This will help you to implement login module according to your needs. For writing your own login module, you will need to inherit from class AbstractLoginModule, so that you will have access to shared objects (like "sharedMap" object, which is shared among all login modules)


              hope this helps,


              • 4. How to write login module?
                Marc Boorshtein Newbie

                Thanks Marek, it did.  I seem to be getting very close.  Instead of writing a custom login module I decided instead to create my own InitiateLoginServlet based on the GenericSSOAgent one.  I'm using the same form and once the token is validated I execute:


                request.getSession().setAttribute("credentials", new Credentials(userName,""));



                This is the same as the generic sso agent implementation.  However once this executes there's a redirect to /portal/private/j_security_check?j_username=root&j_password=rememberme-123456


                this step fails.  the cookies all appear to be the same, am I missing a step?




                • 5. How to write login module?
                  Marek Posolda Expert

                  Hi Marc,

                  it looks correct for me, call to super.doGet() should perform saving credentials into TokenStore. So that should be fine.


                  One thing, which is coming to my mind, is your login module configuration. Are you using SSOLoginModule and JbossLoginModule? You need to use these two because password is empty and so default configuration with PortalLoginModule, SharedStateLoginModule and JbossLoginModule can't work for you.


                  The difference is that SSOLoginModule don't do any authentication because it assumes that authentication has been already done by SSO server and validated by SSOAgent. Especially SSOLoginModule doesn't call Authenticator.validateUser() which is called by SharedStateLoginModule.

                  • 6. How to write login module?
                    Marc Boorshtein Newbie

                    To answer your questions, yes.  I'm using the standard config in  GateIn-3.1.0-GA/server/default/deploy/gatein.ear/META-INF/gatein-jboss-beans.xml



                          <login-module code="org.gatein.sso.agent.login.SSOLoginModule" flag="required">



                          <login-module code="org.exoplatform.services.security.j2ee.JbossLoginModule" flag="required">

                            <module-option name="portalContainerName">portal</module-option>

                            <module-option name="realmName">gatein-domain</module-option>




                    I'm not sure what you mean by "Especially SSOLoginModule doesn't call Authenticator.validateUser() which is called by SharedStateLoginModule"  I see that SharedStateLoginModule is configured in the default authentication tag.  I'm triggering this process by first clicking on the "Sign In" in the upper right hand corner of the public portal then hitting submit (this solution is a reverse proxy system so the login has already happened once the user reaches the portal).




                    • 7. How to write login module?
                      Marc Boorshtein Newbie

                      I turned up the logging to debug and this is what I see:


                      15:01:25,304 DEBUG [InitiateLoginServlet] Login initiated with credentials in session, performing authentication

                      15:01:25,425 DEBUG [RepositoryServiceImpl] RepositoryServiceimpl() getRepository repository

                      15:01:25,425 DEBUG [XASessionImpl] Enlist session: __system@portal-work, org.exoplatform.services.jcr.impl.core.XASessionImpl@444ea76c

                      15:01:25,425 DEBUG [SessionDataManager] getItemByIdentifier(00exo0jcr0root0uuid0000000000000 ) >>>>>

                      15:01:25,425 DEBUG [SessionDataManager] getItemByIdentifier(00exo0jcr0root0uuid0000000000000) --> /  <<<<< 0.0sec

                      15:01:25,426 DEBUG [SessionDataManager] getItem([]:1 + []autologin ) >>>>>

                      15:01:25,426 DEBUG [SessionDataManager] getItem([]:1 + []autologin) --> /autologin <<<<< 0.0sec

                      15:01:25,428 DEBUG [SessionDataManager] getItemByIdentifier(00exo0jcr0root0uuid0000000000000 ) >>>>>

                      15:01:25,428 DEBUG [SessionDataManager] getItemByIdentifier(00exo0jcr0root0uuid0000000000000) --> /  <<<<< 0.0sec

                      15:01:25,429 DEBUG [SessionDataManager]  ----- commit --------




                      15:01:25,429 DEBUG [TransactionableDataManager] save() org.exoplatform.services.jcr.impl.dataflow.session.TransactionableDataManager@7d1c67d txStarted: false

                      ====== Changes ======





                      15:01:25,429 DEBUG [XASessionImpl] Logout. Session: __system@portal-work, org.exoplatform.services.jcr.impl.core.XASessionImpl@444ea76c

                      15:01:25,429 DEBUG [TransactionableDataManager] tx rollback() org.exoplatform.services.jcr.impl.dataflow.session.TransactionableDataManager@7d1c67d[NULL]

                      15:01:25,429 DEBUG [XASessionImpl] Delist session: __system@portal-work, org.exoplatform.services.jcr.impl.core.XASessionImpl@444ea76c

                      15:01:25,429 WARN  [ErrorLoginServlet] Cannot delete the token ''

                      org.chromattic.api.UndeclaredRepositoryException: javax.jcr.RepositoryException: Illegal relPath: ""

                                at org.chromattic.core.DomainSession.getChild(DomainSession.java:321)

                                at org.chromattic.core.EntityContext.getChild(EntityContext.java:239)

                                at org.chromattic.core.mapper.onetomany.hierarchical.AnyChildMap.get(AnyChildMap.java:54)

                                at org.exoplatform.web.security.security.TokenContainer.removeToken(TokenContainer.java:60)

                                at org.exoplatform.web.security.security.CookieTokenService$3.execute(CookieTokenService.java:104)

                                at org.exoplatform.web.security.security.CookieTokenService$3.execute(CookieTokenService.java:100)

                                at org.exoplatform.web.security.security.CookieTokenService$TokenTask.execute(CookieTokenService.java:171)

                                at org.exoplatform.commons.chromattic.ContextualTask.executeWith(ContextualTask.java:45)

                                at org.exoplatform.web.security.security.CookieTokenService.deleteToken(CookieTokenService.java:100)

                                at org.exoplatform.web.security.security.CookieTokenService.deleteToken(CookieTokenService.java:38)

                                at org.exoplatform.web.login.ErrorLoginServlet.unregisterTokenCookie(ErrorLoginServlet.java:93)

                                at org.exoplatform.web.login.ErrorLoginServlet.doGet(ErrorLoginServlet.java:65)

                                at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)

                                at org.exoplatform.container.web.AbstractHttpServlet.onService(AbstractHttpServlet.java:167)

                                at org.exoplatform.container.web.AbstractHttpServlet.service(AbstractHttpServlet.java:116)

                                at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

                                at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:638)

                                at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:444)

                                at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:382)

                                at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:310)

                                at org.apache.catalina.authenticator.FormAuthenticator.forwardToErrorPage(FormAuthenticator.java:337)

                                at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:260)

                                at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:417)

                                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)

                                at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)

                                at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)

                                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

                                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

                                at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)

                                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

                                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)

                                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)

                                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)

                                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)

                                at java.lang.Thread.run(Thread.java:636)

                      Caused by: javax.jcr.RepositoryException: Illegal relPath: ""

                                at org.exoplatform.services.jcr.impl.core.LocationFactory.parseNames(LocationFactory.java:250)

                                at org.exoplatform.services.jcr.impl.core.LocationFactory.parseRelPath(LocationFactory.java:97)

                                at org.exoplatform.services.jcr.impl.core.NodeImpl.hasNode(NodeImpl.java:1288)

                                at org.chromattic.core.jcr.SessionWrapperImpl.getChild(SessionWrapperImpl.java:193)

                                at org.chromattic.core.DomainSessionImpl._getChild(DomainSessionImpl.java:706)

                                at org.chromattic.core.DomainSession.getChild(DomainSession.java:318)

                                ... 36 more


                      It looks like I'm missing a config somewhere?

                      • 8. How to write login module?
                        Marek Posolda Expert

                        When your authentication is happening before user reaches portal, then you should use SSOLoginModule and JbossLoginModule. That's what I meant. From stacktrace, it seems that you have "rememberme" cookie in your browser. Can you try to remove it and login again with unchecked checkbox "Remember my login" from login screen? Another thing is that stacktrace is thrown from ErrorLoginServlet so authentication failed for you in login modules. Can you try to enable debugging for login modules as well?


                        And which version of GateIn are you using?


                        It may be good for you to monitor HTTP requests and responses during login process to see where can be issue.

                        • 9. How to write login module?
                          Marc Boorshtein Newbie

                          The version of GateIn is 3.1 final.  The system I am integrating with is a reverse proxy.  If I disable SSO and login via a username and password through the reverse proxy everything works fine.  I'm compared wireshark traces between the reverse proxy and going directly to the portal are identical.  My hunch is (I will test tonight but any thoughts you have would be appreciated) that since my GateIn instance is using a directory for authentication and authorization something is getting confused.  Based on my analysis so far this is what it looks like is happening:


                          1.  authenticate to the reverse proxy

                          2.  access /portal/private

                          3.  My custom InitiateLoginServlet is executing and generating the correct Credentials object

                          4.  At some point something is supposed to be generating a set of temporary credentials

                          5.  The user is redirected to /portal/private/j_security_check?j_username=root&j_password=rememberme-123456 probably to satisfy an internal requirement.  the j_password is temporary and one time use for this purpose

                          6.  Because #4 isn't happening jboss is rejecting the authentication


                          I'm going to try removing the directory from the configuration so it is just using the identity  store to see if I have the same issue.


                          Any thoughts?




                          • 10. How to write login module?
                            Marc Boorshtein Newbie

                            SOLVED!  Sort of.


                            So the way I solved this leads me to think that there's an issue with the SSOLoginModule shipped with GateIn.  What I did was take http://anonsvn.jboss.org/repos/gatein/components/sso/trunk/agent/src/main/java/org/gatein/sso/agent/login/SSOLoginModule.java and put it in my own package, packaged it in my jar and configured it in server/default/deploy/gatein.ear/META-INF/gatein-jboss-beans.xml and it started working.  This leaves me to think that the SSOLoginMOdule that ships with GateIn has an issue.




                            • 11. How to write login module?
                              macois Newbie

                              Hi Marc !!


                              I'm very interested by your correction, i've encountered the same problem as you !

                              Could you give your repackage jar (sso-agent-1.0.1-GA.jar) with the SSOLoginMOdule corrected plz ?


                              Thanks by advance,



                              • 12. How to write login module?
                                Marc Boorshtein Newbie



                                When I say I repackaged it, I mean I put it in a new java package.  I replaced org.gatein.sso.agent.login with com.blah.blah... for the system I'm building and compiled it.  I didn't repackage sso-agent-1.0.1-GA.jar.  You could probably just compile the class as is if you wanted to or just change the java package to something else.




                                • 13. How to write login module?
                                  macois Newbie

                                  Okay thanks for the information.