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?