4

How to redirect user to home page if user is already logged. I use Filter class for login page but it doesn't work properly. my code is:

@WebFilter(filterName = "loginFilter",
urlPatterns ={"/login.xhtml"})
public class LoginFilter implements Filter{

    private FilterConfig filterconfig;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterconfig = filterconfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httprequest =(HttpServletRequest) request;
        HttpServletResponse httpresponse =(HttpServletResponse) response;
        try{
        if(httprequest.getUserPrincipal() != null){

            System.out.printf("User authenticated with " + httprequest.getRemoteUser() + " username conected.");
            httprequest.getRequestDispatcher("/home.xhtml").forward(request, response);
        } else{
            chain.doFilter(request, response);
        }
        }catch(Exception){
            //do something
        }

    }

    @Override
    public void destroy() {
        System.out.print("Existing from loginFilter");
    }

}

Here is my problem: user logged to web and do some navigation and things and back to login page using browser's back button without logout and again enter username password then press login button. Then it throws exception IndexOutofBoundsException. I just need to check when user navigate to login page using either link or browser's back button, and redirect to home page. any suggestion?

Odgiiv
  • 683
  • 1
  • 11
  • 32

2 Answers2

3

Just tell the browser to not cache the login page. Add the following lines to the filter directly after you've casted the response to httpresponse.

httpresponse.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
httpresponse.setHeader("Pragma", "no-cache"); // HTTP 1.0.
httpresponse.setDateHeader("Expires", 0); // Proxies.

Otherwise the browser would give the page from cache on back button instead of sending a fullworthy request of the server which should trigger the filter.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Yeah thanks I add another filter class including these header data. I set urlpattern like "/*" so it works for all pages. I think it should work properly. – Odgiiv Jan 11 '13 at 13:45
  • 1
    `/*` is pretty overly generic. Remember to skip CSS/JS/image resources otherwise webapp performance will greatly be hit. See also http://stackoverflow.com/questions/10305718/avoid-back-button-on-jsfprimefaces-application/10305799#10305799 – BalusC Jan 11 '13 at 13:47
0

Better than a filter in my opinion with also using BalusC's tip:

<f:view>
    <f:metadata>
        <f:viewAction action="#{login.checkLogin()}"/>
    </f:metadata>

     ...
</f:view>

public String checkLogin() {
    if (getRequest().getRemoteUser() != null) {
        getResponse().setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        getResponse().setHeader("Pragma", "no-cache"); // HTTP 1.0.
        getResponse().setDateHeader("Expires", 0); // Proxies.
        return "Home";
    }

    return null;
}

I don't think you should break the filter chaining like that, there might be another important filter in the chain you are not aware of.

ChRoNoN
  • 860
  • 8
  • 18