15.3.2. Writing an authentication method

The authenticate-method property specified for identity in components.xml specifies the method used by SeamLoginModule to authenticate users. This method takes no parameters, and is expected to return a Boolean indicating authentication success or failure. Username and password are obtained from Credentials.getUsername() and Credentials.getPassword() respectively. (A reference to the credentials component can be obtained via Identity.instance().getCredentials().) Any role that the user is a member of should be assigned with Identity.addRole(). The following is a complete example of an authentication method inside a POJO component:
@Name("authenticator")
public class Authenticator {
  @In EntityManager entityManager;
  @In Credentials credentials;
  @In Identity identity;

  public boolean authenticate() {
    try {
      User user = (User) entityManager.createQuery(
          "from User where username = :username and password = :password")
          .setParameter("username", credentials.getUsername())
          .setParameter("password", credentials.getPassword())
          .getSingleResult();

      if (user.getRoles() != null) {
        for (UserRole mr : user.getRoles())
          identity.addRole(mr.getName());
        }

        return true;
      } catch (NoResultException ex) {
        return false;
      }

   }

}
In the example, both User and UserRole are application-specific entity beans. The roles parameter is populated with roles that the user is a member of. This is added to the Set as literal string values — for example, "admin", "user", etc. If the user record is not found, and a NoResultException is thrown, the authentication method returns false to indicate authentication failure.

Note

It is important to keep authenticator methods minimal and free from any side-effects — they can be invoked multiple times during a single request, so any special code that should execute when authentication succeeds or fails should implement an event observer. See Section 15.10, “Security Events” later in this chapter for more information about events raised by Seam Security.

15.3.2.1. Identity.addRole()

The Identity.addRole() method's behavior depends upon current session authentication. If the session is not authenticated, addRole() should only be called during the authentication process. When called here, the role name is placed in a temporary list of pre-authenticated roles. Once authentication succeeds, the pre-authenticated roles then become "real" roles, and calling Identity.hasRole() for those roles returns true. The following sequence diagram represents the list of pre-authenticated roles as a first class object to clarify its position in the authentication process.
If the current session is already authenticated, then calling Identity.addRole() grants the specified role to the current user immediately.