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?