0

I have a JSF web application where all the pages that reside under directory web needs to be protected from unautheticatd use i.e., user should be in session to accesss these pages. I am using filter to validate the session for these pages. These pages are accessed via url like : /contextRoot/web/download.xhtml or /contextRoot/web/sign/upload.xhtml. Whereas other pages that reside outside web directory or in some other directory need not to go pass through session validation filter. My filter is like:

@WebFilter(filterName = "AuthenticationFilter", urlPatterns={"/web/*"}, dispatcherTypes   = {DispatcherType.REQUEST})

public class AuthenticationFilter implements Filter {

    private static final boolean debug = true;
    
    private FilterConfig filterConfig = null;

    public AuthenticationFilter() {
    }

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

        if (debug) {
            log("AuthenticationFilter:doFilter()");
        }
        HttpSession session = ((HttpServletRequest) request).getSession(false);
        if (session == null || session.getAttribute("username") == null) {
            System.out.println("Your Session Not Active. You are redirected.");
            //((HttpServletResponse) response).sendRedirect("home.xhtml");
        } else {
            System.out.println("Your Session is active. username : " + session.getAttribute("username"));
        }

        Throwable problem = null;
        try {
            chain.doFilter(request, response);
        } catch (Throwable t) {
            // If an exception is thrown somewhere down the filter chain,
            // we still want to execute our after processing, and then
            // rethrow the problem after that.
            problem = t;
            t.printStackTrace();
        }
    }
}

I am using urlPattern /web/* so that every page inside web directory will go pass this filter. The filter is right now just printing stuff for debugging. But whenever I am accessing page inside web directory or any other page, it is not going through filter. I also tried using /faces/web/* as urlPattern but that also didn't work. But when I put /* as urlPattern, every accessed page goes through the filter. I am accessing page as
http://localhost:8080/CodesignWebApp/faces/web/sign/SelectServer.xhtml http://localhost:8080/CodesignWebApp/faces/web/sign/FileUpload.xhtml?signmethod=MICROSOFT

I am suspecting something wrong with urlPattern.

vinS
  • 1,417
  • 5
  • 24
  • 37
Akhil
  • 533
  • 2
  • 11
  • 26
  • *"My pages are actually not directly under web, they are like web/sign/sign.xhtml"* This is very vague and confusing. Please elaborate that part. Better yet, let's start at the very beginning: please copypaste exact URLs you're actually using in webbrowser's address bar for which you'd like to invoke this filter. – BalusC Aug 27 '14 at 07:35
  • Exact URLs for pages are added. – Akhil Aug 27 '14 at 07:41
  • Okay. Well, `/faces/web/*` is then the one you need. How exactly does that fail? Was you sure you're running the code you think you're running? (rebuild, redeploy, etc after changing URL pattern, it's namely initialized only once during startup). A better alternative is to get rid of ancient JSF 1.0 style `/faces/*` path mapping altogether and replace it by `*.xhtml`. – BalusC Aug 27 '14 at 07:43

1 Answers1

1

I am accessing page as

http://localhost:8080/CodesignWebApp/faces/web/sign/SelectServer.xhtml
http://localhost:8080/CodesignWebApp/faces/web/sign/FileUpload.xhtml

The URL pattern of a @WebFilter (and @WebServlet) must match exactly those URLs you see in browser's address bar (and thus not the disk file system paths you actually have in the server side; it's also literally called an "URL pattern", not "file pattern" or whatever).

So, all in all, just this should do, provided that /CodesignWebApp is webapp's context root:

@WebFilter("/faces/web/*")
public class AuthenticationFilter implements Filter {
    // ...
}

(filter name is not relevant and request dispatcher method you specified is the default already)

A different alternative is to get rid of ancient JSF 1.0 style /faces/* mapping altogether and replace it by the JSF 2.0 style *.xhtml mapping. You don't want the endusers to see raw JSF source code when they remove /faces part from the URL, right?

<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

This way you can just access the pages as follows:

http://localhost:8080/CodesignWebApp/web/sign/SelectServer.xhtml
http://localhost:8080/CodesignWebApp/web/sign/FileUpload.xhtml

And map the filter as follows:

@WebFilter("/web/*")
public class AuthenticationFilter implements Filter {
    // ...
}

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555