JSF HTTP Session Login

You can in JSF get/set HTTP session attributes via ExternalContext#getSessionMap() which is basically a wrapper around HttpSession#get/setAttribute().

@Named
@RequestScoped
public class LoginController {

    private String username;
    private String password;

    @EJB
    private UserService userService;

    public String login() {
        User user = userService.find(username, password);
        FacesContext context = FacesContext.getCurrentInstance();

        if (user == null) {
            context.addMessage(null, new FacesMessage("Unknown login, try again"));
            username = null;
            password = null;
            return null;
        } else {
            context.getExternalContext().getSessionMap().put("user", user);
            return "userhome?faces-redirect=true";
        }
    }

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "index?faces-redirect=true";
    }

    // ...
}

In the Facelets page, just bind the username and password input fields to this bean and invoke login() action accordingly.

<h:form>
    <h:inputText value="#{loginController.username}" />
    <h:inputSecret value="#{loginController.password}" />
    <h:commandButton value="login" action="#{loginController.login}" />
</h:form>

Session attributes are directly accessible in EL. A session attribute with name user is in EL available as #{user}. When testing if the user is logged in some rendered attribute, just check if it’s empty or not.

<h:panelGroup rendered="#{not empty user}">
    <p>Welcome, #{user.fullName}</p>
    <h:form>
        <h:commandButton value="logout" action="#{loginController.logout}" />
    </h:form>
</h:panelGroup>

The logout action basically just trashes the session.


As to checking an incoming request if an user is logged in or not, just create a Filter which does roughly the following in doFilter() method:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {    
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);
    String loginURI = request.getContextPath() + "/login.xhtml";

    boolean loggedIn = session != null && session.getAttribute("user") != null;
    boolean loginRequest = request.getRequestURI().equals(loginURI);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);

    if (loggedIn || loginRequest || resourceRequest) {
        chain.doFilter(request, response);
    } else {
        response.sendRedirect(loginURI);
    }
}

Map it on an url-pattern covering the restricted pages, e.g. /secured/*, /app/*, etc.

See also:

Leave a Comment