Authentication method only fires once
cash1981 Jun 25, 2009 1:04 PMI have modified the seam login to identify a user and retrieve its email and send a one-time generated password which needs to be correctly entered before I correctly login the user.
This works fine. The only problem is that if the user enters the wrong one-time password and tries again, then the authenticator method isnt executed anymore. Why, I don't know.
So my login.xhtml contains a username/password field which the user enters.
That executes a action class that checks the username/password and sends an email.
Then I render this div:
<s:div rendered="#{oneTimePasswordIsSent}">
<h:messages showSummary="true" showDetail="true" globalOnly="true" />
<h:form>
<h:outputLabel for='onepw'>Onetimepassword</h:outputLabel><h:inputText id="onepw" value="#{myOnetimepw}"/>
<br/>
<h:commandButton id="loginBtn" styleClass="actionButton" value="Login" action="#{identity.login}" title="Login" />
<s:button styleClass="actionButton" value="Retry" action="#{loggInn.relogin}" title="Retry"/>
</h:form>
</s:div>My authenticator class:
@Name("authenticator")
public class Authenticator {
@Logger
private Log log;
@In
private Identity identity;
@In
private Credentials credentials;
@In(scope=ScopeType.SESSION)
private Long timeoutTimer;
@In(scope=ScopeType.SESSION)
private Boolean oneTimePasswordIsSent;
@In(value="theActualOnetimePassword", scope = ScopeType.SESSION)
private String otherOnetimepw;
@Out(required = false)
@In(required = false)
private String myOnetimepw;
@In(create = true)
private ProcessUser currentUser;
/***
* Authenticates the user according to the username, password, one-time password and
* organization.
*
* @return
*/
public boolean authenticate() {
try {
if(!oneTimePasswordIsSent)
throw new NullPointerException("Onetime password is not sent");
if (currentUser.getId() == 0L)
throw new NullPointerException("Didnt find any user");
credentials.setUsername(currentUser.getUsername());
credentials.setPassword(currentUser.getPasswordHash());
//Find out if the one hour has passed
final long now = System.currentTimeMillis();
final long timer = timeoutTimer.longValue();
if(timer == 0L)
throw new NullPointerException("Error, couldnt get timeoutTimer");
final long actualTime = timer - now;
if(actualTime / 1000 > 3600) {
throw new Exception("1 hour passed since onetime pass is sent, relogin please");
}
if(!MyString.empty(myOnetimepw) && !myOnetimepw.trim().equals(otherOnetimepw)) {
throw new Exception("Onetime passwords didn't match");
}
final Set<Role> roles = currentUser.getRoles();
for (Role role : roles) {
identity.addRole(role.getName());
}
Events.instance().raiseEvent("Authenticator.authenticated", currentUser, true);
return true;
} catch (NoResultException ex) {
//logFailedAttempt();
log.error(ex);
return false;
} catch (Exception ot) {
//logFailedAttempt();
log.error(ot);
return false;
}
}
/*
* If the user is valid then log failed login attempts
*/
private void logFailedAttempt() {
if(currentUser.getId() != 0L) {
Events.instance().raiseAsynchronousEvent("loginFailed", credentials.getUsername(), currentUser.getOrganization() != null ? currentUser.getOrganization().getName() : "");
}
}
}
The authenticator method is executed the first time, but if wrong password is entered and it returns false, It is never executed again.
Does anyone spot the problem?