tomcatservletsforwardbasic-authenticationcross-context

Forwarding to another webapp with authentication


I was trying out my first web app. Using Tomcat 7.

I want to forward from host:port/app1/x/y with some post data and authentication headers to host:port/app2/x/y with the same post data and the headers. Both the applications are on the same host.

/app2 has basic authentication. On the client side the code goes

method.addRequestHeader("Authorization",
    "Basic " + new String(Base64.encodeBase64(userNPasswd.getBytes())));

I am able to forward from /app1 to /app2 by doing the following

1) Implementing a Filter and doing this in the doFilter in /app1

ServletContext othercontext = filterConfig.getServletContext().getContext("/app2");
RequestDispatcher dispatcher = othercontext.getRequestDispatcher(req.getRequestURI().replace("/app1", ""));
dispatcher.forward(request, response);

2) In app1.. under WEB-INF/web.xml forward all (/*) url mapping

<filter>
    <filter-name>ForwardFilter</filter-name>
    <filter-class><my.package.filter.ForwardFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>ForwardFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3) In tomcat in conf/server.xml.. Defining context for both /app1 and /app2 under the same host and turning off unpack war etc and having crossContext = true

<Context path="/app1" docBase="app1" crossContext="true" />
<Context path="/app2" docBase="app2" crossContext="false" /> 

app1.war is a really simple with just one filter class and a web.xml which is mapped to forward requests

app2.war is a spring enabled web app

When i directly make a request to /app2 with a wrong password, I get an error

When I am forwarding the way currently forwarding (from /app1 to /app2), it is skipping the authentication and the request start processing under /app2. It fails with npe when in some place in /app2.. it is trying to read the user name from the security context (Spring was expected to kick in and set this)

SecurityContextHolder.getContext().getAuthentication().getName();

I cannot change code under /app2

I would like /app1 to be a very simple request forward..
I cannot use redirect or use a apache rule rewrite in front of tomcat

Please let me know if any more information has to be shared

Does a forward also forward all the authentication headers as well, so its as though the request hit /app2 directly ?


Solution

  • By default filters are not applied for forwards. It needs to be specified explicitly to apply for forwards as well

    So in the WEB-INF/web.xml of the receiving app (here app2), for every filter which should be applied to the forward request as well add the following

    <filter-mapping>
    ...
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    ...
    <filter-mapping>
    

    After that all the required filters in /app2 started executing as well