开发者

Seam IdentityStore NullpointerException for Tokenbased rememberMe

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

EDIT: 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);

EDIT: Ok, seems like i have have to "install" the component in the components.xml and to override the JpaIdentityStore, at least the lookupUser method until now.


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 use 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.

  • 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());
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜