Wesley Egbertsen
Wesley Egbertsen

Reputation: 710

WebFilter and RewriteConfiguration conflict

So I have this RewriteConfiguration:

@RewriteConfiguration
public class ApplicationConfigurationProvider extends HttpConfigurationProvider {

    /**
     * Set the forwarding rules
     * @param context
     * @return The forwarding rules
     */
    @Override
    public Configuration getConfiguration(ServletContext context) {
        return ConfigurationBuilder.begin()
                .addRule()
                .when(Path.matches("/secure/{path}.xhtml?"))
                .perform(Log.message(Level.INFO, "Server requested path: /secure/{path}"))
                .addRule(Join.path("/login").to("/public/login.xhtml"))
                .perform(Log.message(Level.INFO, "Forwarded: login"))
                .addRule()
                .when(Path.matches("/{path}").andNot(Path.matches("/login")))
                .perform(Log.message(Level.INFO, "Forwarded': {path}"))
                .addRule()
                .when(Path.matches("/{path}"))
                .perform(Forward.to("/secure/{path}.xhtml"))
                ;
    }

    /**
     *
     * @return
     */
    @Override
    public int priority() {
        return 0;
    }

}

And this filter:

@WebFilter(filterName = "AuthorizationFilter", urlPatterns = {"/secure/*"})
public class AuthorizationFilter implements Filter {

    /**
     * Function that filters out unauthorized users and returns them to the login page
     * when they try to visit secured pages
     * @param request
     * @param response
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest req = (HttpServletRequest) request;
        AuthorizationBean auth = (AuthorizationBean) req.getSession().getAttribute("authBean");        
        if (auth == null || !auth.isLoggedIn()) {
            // User is not logged in, so redirect to login page.
            HttpServletResponse res = (HttpServletResponse) response;
            res.sendRedirect(req.getContextPath() + "/public/login.xhtml");
        } else {
            // User is logged in, so just continue request.
            chain.doFilter(request, response);
        }
    }

    /**
     *
     */
    @Override
    public void destroy() {
    }

    /**
     *
     * @param fc
     */
    @Override
    public void init(FilterConfig fc) {
    }

}

The problem I have facing is that, when I for example access the page "http://localhost:8080/webapp/profile" profile is a file in secure, so there is a page "/secure/profile.xhtml", but because of the rewriteConfiguration, just "profile" also works. But the problem is that the WebFiler doesn't capture "profile" it only captures "http://localhost:8080/webapp/secure/profile.xhtml".

Is there a way that the rewrited pages out of "secure" also get captured with the filter? So that when I access the page "profile" it's handled the same as "/secure/profile.xhtml".

Upvotes: 2

Views: 449

Answers (1)

BalusC
BalusC

Reputation: 1108642

This construct will indeed fail as described when the rewrite filter runs before the authentication filter, and the rewrite filter performs internally a RequestDispatcher#forward() call on the target source.

Filters listen by default on direct requests only. You'd need to explicitly add the FORWARD dispatcher to let the filter listen on forwarded requests too.

@WebFilter(
    filterName = "authorizationFilter", 
    urlPatterns = {"/secure/*"},
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD}
)

Or in web.xml flavor:

<filter-mapping>
    <filter-name>authorizationFilter</filter-name>
    <url-pattern>/secure/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

Upvotes: 4

Related Questions