简体   繁体   中英

JSF Redirect causes exception in a filter

I have configured an authentication filter for any pages that I wanted to protect. However when it tries to redirect to the login page, I am encountering below error

com.sun.faces.context.FacesFileNotFoundException

..here's my filter

@WebFilter(filterName = "Authentication Filter", urlPatterns = { "/pages/*" }, dispatcherTypes = {
        DispatcherType.REQUEST, DispatcherType.FORWARD })
public class AuthenticationFilter implements Filter {
    static final Logger logger = Logger.getLogger(AuthenticationFilter.class);
    private String contextPath;

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        if (httpRequest.getUserPrincipal() == null) {
            httpResponse.sendRedirect(contextPath
                    + "/faces/pages/public/login.xhtml");
            return;
        }
        chain.doFilter(request, response);
    }
    public void init(FilterConfig fConfig) throws ServletException {
        contextPath = fConfig.getServletContext().getContextPath();
    }
}

..and my web.xml is mapped with this code for the faces servlet

<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>

Not sure but I have verified that the path is existing in my project folder

+pages
    +public
        -login.xhtml

The generated path is

http://localhost:8080/MyApp/faces/pages/public/login.xhtml

Anybody knows the reason?

The exception indicates that JSF is not able to locate the view. Does your project have this directory structure: contextRoot/faces/pages/public/login.xhtml ?

/faces path prefix is usually added by default to the faces url-pattern by some IDEs (ie NetBeans). You probably have changed it from web.xml but you haven't removed if from the filter sendRedirect argument.

In order to make your filter work, either remove the /faces prefix from sendRedirect() method in the filter:

httpResponse.sendRedirect(contextPath + "/pages/public/login.xhtml");

or add it to web.xml like that:

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

Finally, be careful that your filter doesn't cause and endless loop. Adding this check before redirecting may be useful:

HttpServletRequest req = (HttpServletRequest) request;
if (!req.getRequestURI().contains("/pages/public/login.xhtml") && httpRequest.getUserPrincipal() == null) {
        // redirect
        return;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM