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());
}
精彩评论