4 Replies Latest reply on Mar 15, 2008 12:44 AM by Shane Bryzak

    Identity.isLoggedIn triggers login

    Eric Nelson Newbie

      By default, it seems that Identity.isLoggedIn() triggers a quietLogin (by calling isLoggedIn(true)).


      This is a problem for applications that need to conditionally display components on a page where a user is allowed to login when there is a count of number of bad logins kept.


      What happens is that the user clicking login is triggering the real login attempt, then on the rerender of the page, at least the first call to Identity.isLoggedIn() seems to be triggering another login attempt.


      The result is that after 2 bad login attempts, authenticator has been triggered 4 times and the user is locked out twice as fast as they should be.


      My question is if this is by design or if this is a defect?  I've fixed my problem by temporarily extending Identity and overriding isLoggedIn, but that's not really an ideal solution.

        • 1. Re: Identity.isLoggedIn triggers login
          Shane Bryzak Master

          The correct way is to write an observer for the org.jboss.seam.security.loginFailed event.

          • 2. Re: Identity.isLoggedIn triggers login
            Eric Nelson Newbie

            I'm not sure I understand.  My problem is not counting the failed logins.  The count is correct.  LDAP was called twice where it should have been called once.


            I could add an observer and use it to set some variable that tells me the user is not logged in, but it would be more straightforward to just ask the Identity object if it has logged in. 


            What is the purpose of isLoggedIn if not to find out if an identity has been logged in?

            • 3. Re: Identity.isLoggedIn triggers login
              Joseph Nusairat Newbie

              I think you have to remember you are not writing an isLoggedIn method ... but an authenticate method.


              I ended up needing to add something to the Identity object. So i wrapped the login and added some observers inside the authenticate. It sounds more complicated than it was (maybe i made it more complicated)


              But basically .... my identity looks like this ...



              @Name("org.jboss.seam.security.identity")
              @Scope(ScopeType.SESSION)
              @Install(precedence = Install.APPLICATION)
              @BypassInterceptors
              @Startup
              public class LdapIdentity extends Identity {
                      @Override
                      public String login() {         
                              String retVal = "";
                              try {
                                      // clear out the login message in case it was triggered
                                      // by an authenticate occurring outside the login
                                      loginErrorMessage = null;                       
                                      retVal = super.login();                 
                              } finally {                     
                                      // check if any error messages were registered from
                                      // this logging., if they are write them out                    
                                      if (StringUtils.isNotBlank(loginErrorMessage)) {
                                              FacesMessages.instance().addFromResourceBundle(loginErrorMessage);
                                      }
                              }               
                              return retVal;
                      }
                      
                  private String loginErrorMessage;
                  
                  /**
                   * This is used to save off an error message in case of a login.
                   * @param message
                   */
                  @Observer("invalidLogin")
                  public void writeInvalidLogin(String message) {             
                      loginErrorMessage = message;            
                  }
              }



              And then in the Authenticator i just add this when i need a message.



              Events.instance().raiseEvent("invalidLogin", "message.login.userPassFail");



              But again the key is just to remember authenticate does not equal login


              (at least thats my understanding)

              • 4. Re: Identity.isLoggedIn triggers login
                Shane Bryzak Master

                The isLoggedIn() method will tell you if the user is logged in, but if they are not logged in and their credentials are already set (due to a cookie or via some other means) then it will attempt to do a silent login, using those credentials.  If you don't want this behaviour, then you can use isLoggedIn(false) instead.


                I mentioned the loginFailed event because of this:




                The result is that after 2 bad login attempts, authenticator has been triggered 4 times and the user is locked out twice as fast as they should be.

                The authenticator should not be responsible for locking out the user, or counting the number of failed login attempts.  The event I mentioned is an accurate way of counting the number of times the user has explicitly attempted to login and failed.