Jun 20, 2011

JSF and Seam Security - custom login in 3 steps

Seam framework provides a standard IdentityManagement API to manage user management and authentication.The Credentials class includes the two basic properties needed to perform user authentication. The username, and the password, (sic).


But some times extra information is needed to authenticate a user. For example a company or an organization idenntification number, etc.

What we can do is simply extend the Credentials class including these properties.In the following scenario an extra company field is added to the login page.



1. Create a new class - CustomCredentials - extending Credentials, which includes the private Company property.
/*
 *@(#)CommCredentials.java  1.00  26/05/2011
 *
 */

package com.comm.security;

import com.comm.entities.Company;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.security.Credentials;

/**
 *
 * @author Charis Arapidis - arapidhs@gmail.com
 * @version 1.00, 26/05/2011
 * @since v1.00
 */
@Name("org.jboss.seam.security.credentials")
@Scope(ScopeType.SESSION)
@Install(precedence = Install.APPLICATION)
@BypassInterceptors
public class CommCredentials extends Credentials {

    /** */
    private Company company;

    /** @return the company */
    public Company getCompany() {
        return company;
    }

    /** @param value the company to set */
    public void setCompany(final Company value) {
        this.company = value;
    }

}
Notice that CustomCredentials is a Seam Component since it extends Credentials and is installed at Application Scope.

2. In the login page add the Company field refering to it with the expression #{credentials.company}
<h:outputLabel for="company" value="#{messages.login_company}:"/>

<h:selectOneMenu id="company" value="#{credentials.company}">
    <s:selectItems value="#{CompaniesList.companies}" var="company"
        itemLabel="#{company.title}"
        noSelectionLabel="#{messages.general_select}"/>
    <f:converter converterId="CompanyConverter" />
</h:selectOneMenu>

<h:commandButton action="#{identity.login}"/>
3. Finally, in the Authenticator class inject the CustomCredentials comopent created earlier providing access to the user submitted Company field.
/*
 *@(#)Authenticator.java  1.00  11/05/2011
 *
 */
package com.comm.security;

import com.comm.entities.Company;
import com.comm.entities.User;
import com.comm.sessionbeans.SecuritySessionBeanLocal;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.international.StatusMessages;

/**
 * @author Charis Arapidis - arapidhs@gmail.com
 * @version 1.00, 11/05/2011
 * @since v1.00
 */
@Name("authenticator")
@Scope(ScopeType.EVENT)
public class Authenticator {

    @In
    private CustomCredentials credentials;
    /** */
    private User loginUser;
    /** */
    @In(create=true)
    private SecuritySessionBeanLocal service;

    /** @return true if user is authenticated */
    public boolean authenticate() {
        
        final String username = credentials.getUsername();
        final String password = credentials.getPassword();
        final Company company = credentials.getCompany();

        final boolean login = service.authenticate(...);

        if (login) {

        }

        return login;
    }

    @Out(value = "loginUser", required = false,
    scope = ScopeType.SESSION)
    public User getLoginUser() {
        return loginUser;
    }

    public void setLoginUser(final User value) {
        this.loginUser = value;
    }

}
Real Time Web Analytics