I have read numerous examples though I seem to have an 'exact' copy of them, so I cannot figure out why my filter will execute when I navigate to /login
instead of /restricted/*
.
I have tried both annotations (as in the example below) and XML to define the WebFilter.
The Webfilter
@WebFilter(filterName = "AuthenticationFilter", servletNames = { "Faces Servlet" }, urlPatterns = { "/restricted/*" } )
public class AuthenticationFilter implements Filter {
@Inject
private SessionManager sessionManager;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("Active AuthenticationFilter");
if (sessionManager.getUser() == null) {
((HttpServletResponse) response).sendRedirect("/login");
}
else {
chain.doFilter(request, response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher>
</filter-mapping>
<filter>
<filter-name>NoCacheFilter</filter-name>
<filter-class>filter.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>filter.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/restricted/*</url-pattern>
</filter-mapping>
Note
Even though the filter is defined in both files, I can assure I am not using both notations at the same time. For the sake of testing and reviewing I however did post them both.
I am new to the use of webfilters, and could not find much about using multiple filters. But what I did read, you can use multiple and they will execute in the order you defined them in web.xml
.
Question
Does anyone have a clue as to why my filter will execute on pages as /login
too?
The app is running on Glassfish 3.1.2.
The <filter-mapping>
matching conditions are not inclusive, they are exclusive.
With the following mapping
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/restricted/*</url-pattern>
</filter-mapping>
you're basically instructing that the filter should be invoked whenever the FacesServlet
is to be invoked or whenever the URL pattern matches /restricted/*
.
This is not an "and" condition as you seemed to expect. Just remove the <servlet-name>
entry.
The proper @WebFilter
declaration would then be
@WebFilter("/restricted/*")
assuming that you don't need a <filter-mapping>
(if the order is irrelevant, for example).