Kathick
Kathick

Reputation: 1405

How to restrict access if user is not logged in

My project has a template main.xhtml and three views login.xhtml, dashboard.xhtml, new.xhtml. Once I login in login.xhtml, the LoginBean will validate and if successful, then it will take to dashboard.xhtml. If user need to create an new record he click the new button which takes to new.xhtml.

But the problem is, if dashboard.xhtml is requested directly from browser, then it is working without login. Do I need to check every view that the user is logged in? How can I achieve this?

Upvotes: 1

Views: 2064

Answers (1)

BalusC
BalusC

Reputation: 1108722

It sounds like as if you're homegrowing authentication. In that case, you need to also homegrow access restriction. That is normally to be done using a servlet filter.

Assuming that you're logging in as follows in a @RequestScoped bean,

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

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

Then you can check for the logged-in user in a @WebFilter("/*") filter as follows:

@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);

    User user = (session != null) ? session.getAttribute("user") : null;
    String loginURL = request.getContextPath() + "/login.xhtml";

    boolean loginRequest = request.getRequestURI().startsWith(loginURL);
    boolean resourceRequest = request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER);

    if (user != null || loginRequest || resourceRequest)) {
        chain.doFilter(request, response);
    } else {
        response.sendRedirect(loginURL);
    }
}

Note thus that this would continue the request when the user is logged in, or when the login page itself is requested directly, or when a JSF resource (CSS/JS/image) is been requested.

If you were using container managed authentication, then the filter would have been unnecessary. See also How to handle authentication/authorization with users in a database?

Upvotes: 1

Related Questions