3 Replies Latest reply on Jul 21, 2011 4:12 PM by Hong Kong

    NullPointer missing IdentityStore RememberMe Token

    Hong Kong Newbie

      Hi,


      I'm using Seam 2.2.Final and followed the instructions on chapter 15.3.5.1. Token-based Remember-me Authentication.




       <security:identity authenticate-method="#{authenticator.authenticate}" />
       <security:remember-me enabled="true" mode="autoLogin" cookie-max-age="604800"/>
       <security:jpa-token-store token-class="com.mydomain.AuthenticationToken" />
       <event type="org.jboss.seam.security.notLoggedIn">
        <action execute="#{redirect.captureCurrentView}"/>
        <action execute="#{identity.tryLogin()}"/>
       </event>
       <event type="org.jboss.seam.security.loginSuccessful">
        <action execute="#{redirect.returnToCapturedView}"/>
       </event>



      When i login and check remember me a new Token is created in the database. But when the session times out and i try to return, i get a NullPointerException


      Caused by: java.lang.NullPointerException
           at org.jboss.seam.security.management.IdentityManager.isUserEnabled(IdentityManager.java:130)
           at org.jboss.seam.security.RememberMe$1.execute(RememberMe.java:306)
           at org.jboss.seam.security.Identity.runAs(Identity.java:743)
           at org.jboss.seam.security.RunAsOperation.run(RunAsOperation.java:75)



      When the identityStore is initalized, identityStore is null after this call.


      protected void initIdentityStore()
         {    
            // Default to JpaIdentityStore
            if (identityStore == null)
            {
               identityStore = (IdentityStore) Component.getInstance(JpaIdentityStore.class, true);
            }



      Do i have to configure an IdentityStore like this


      <security:jpa-identity-store
          user-class="com.domain.model.UserAccount"
          role-class="com.domain.model.UserRole"/>



      where i have to say i'm not sure what to put inside, and what additional annotations are required, especially where it's not mentioned in the documenation to be required.


      thx

        • 1. Re: NullPointer missing IdentityStore RememberMe Token
          Hong Kong Newbie

          This message would be printed, where does he has to find the method. It is not contained in the factories map in the seam.core.Init class.
             


          if ( log.isTraceEnabled() ) log.trace("Seam component not found: " + name);



          • 2. Re: NullPointer missing IdentityStore RememberMe Token
            Hong Kong Newbie

            Ok, i enabled the JpaIdentityStore in the components.xml it seems i really have to implement my own IdentityStore or at least the lookup method.

            • 3. Re: NullPointer missing IdentityStore RememberMe Token
              Hong Kong Newbie

              Just to sum up the problems i encountered. The documentation in chapter 15.3.5.1. covers just half of the points that are required.


              - RememberMe makes us of the IdentityManager, which itself uses die IdentityStore, which is not enabled by default. So
              <component class="org.jboss.seam.security.management.JpaIdentityStore"/> is required.


              - Further requires the JpaIdentityStore some configuration mentioned in 15.4.2.. But my username was not part of the account object (it was contained in a list in the account object) and my Roles were no entity just an enum (ok that could have been changed). Anyway i skipped the configuration in 15.4.2 and have overwritten the isUserEnabled() and getImpliedRoles methods.


              - You should add Identity.tryLogin(), but with tryLogin() a silent Login is triggered which does not raise the LoginSuccessful event. To return to the captured page.


              <event type="org.jboss.seam.security.notLoggedIn">
                  <action execute="#{redirect.captureCurrentView}"/>
                  <action execute="#{identity.tryLogin()}"/>
                </event>
                <event type="org.jboss.seam.security.loginSuccessful">
                  <action execute="#{redirect.returnToCapturedView}"/>
                </event>



              I made my own authenticator.tryLogin() where I call identity.tryLogin() and afterwards i fire the loginSuccessful event. The problem now ist, all this events occur in one row and both, captureCurrentView and returnToCapturedView are doing a redirect where the first one is executed so i get to the signon page. Will check it out tomorrow.


              - RememberMe default behavior is to invalidate all tokens of a user if his token does not exist. So everyone can set the cookie with the username of someone else to invalidate all his token.


              if (tokenStore.validateToken(decoded.getUsername(), decoded.getValue()))
                          {
                             credentials.setUsername(decoded.getUsername());
                             credentials.setPassword(decoded.getValue());               
                          }
                          else
                          {
                             // Have we been compromised? Just in case, invalidate all authentication tokens
                             tokenStore.invalidateAll(decoded.getUsername());
                          }