2

I'm trying to accomplish a jsf2-based form login where a user can go straight to his chosen URL after being redirected to the login-page. How can this be accomplished? My current settings are as following (using glassfish 3)

Web.XML

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.jsf</form-login-page>
        <form-error-page>/login.jsf</form-error-page>
    </form-login-config>
</login-config>
<security-constraint> //(omitted) all pages except login.jsf requires login </security-constraint>

Session scoped managed bean handling login

public String login(){
    try{
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        request.login(username, pwd);
        loggedInUser = userBean.findByLogin(username);
        username = null;
        pwd = null;
        //context.getExternalContext().redirect((String)request.getAttribute("from"));
        return "/index?faces-redirect=true";

    } catch(Exception e){
        logger.log(Level.FINE, "login failed: {0}", e.getMessage());
        JsfUtil.addErrorMessage("Login failed");
        return null;
    }
}

From another question i got the tip to use a filter instead of the contained handled redirect to the login page, and store the URL before redirect as an attribute in the request like this:

public class LoginFilter implements Filter {
    private String loginPage = "/login.jsf";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
        ServletException {
        if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            // is session expire control required for this request?
            if (httpServletRequest.getUserPrincipal() == null) {
                // User is not logged in, redirect to login page.
                httpServletRequest.setAttribute("from", httpServletRequest.getRequestURI());
                httpServletResponse.sendRedirect(loginPage);
            }
            else
                filterChain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
    }

}

With the url-pattern set to the same as the sum of all security constraints. The problem is how to combine this with the container based login. Leaving login-config auth method as FORM causes the filter to not be executed. Removing it sets the auth-method to BASIC which 1. causes my form to not appear, and 2. httpServletRequest.getUserPrincipal() is automatically set by the web browser to a cached value, so even if the filter is executed, the if-statement will always be false. From what i know, there is no way to keep the browser from doing this, even if the session is invalidated.

Is there any solution to this?

4

0 回答 0