0

我正在尝试我的第一个网络应用程序。使用 Tomcat 7。

我想从 host:port/app1/x/y 与一些 post 数据和身份验证标头转发到 host:port/app2/x/y 具有相同的 post 数据和标头。两个应用程序都在同一台主机上。

/app2 具有基本身份验证。在客户端,代码运行

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

我可以通过执行以下操作从 /app1 转发到 /app2

1) 实现一个过滤器并在 /app1 的 doFilter 中执行此操作

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

2)在app1..WEB-INF/web.xml下转发所有(/*)url映射

<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) 在 conf/server.xml 中的 tomcat 中。为同一主机下的 /app1 和 /app2 定义上下文并关闭 unpack war 等并让 crossContext = true

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

app1.war 非常简单,只有一个过滤器类和一个映射到转发请求的 web.xml

app2.war 是一个支持 spring 的 web 应用程序

当我使用错误的密码直接向 /app2 发出请求时,出现错误

当我转发当前转发的方式(从/app1到/app2)时,它正在跳过身份验证和/app2下的请求开始处理。当在 /app2 中的某个地方时,它会因 npe 失败。它正在尝试从安全上下文中读取用户名(预计 Spring 会启动并设置它)

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

我无法更改 /app2 下的代码

我希望 /app1 是一个非常简单的转发请求。
我不能在 tomcat 前使用重定向或使用 apache 规则重写

如果需要分享更多信息,请告诉我

转发是否也转发所有身份验证标头,所以它好像请求直接命中 /app2 ?

4

1 回答 1

1

默认情况下,过滤器不适用于转发。也需要明确指定才能申请转发

因此,在接收应用程序(此处为 app2)的 WEB-INF/web.xml 中,对于应该应用于转发请求的每个过滤器,还添加以下内容

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

之后 /app2 中所有必需的过滤器也开始执行

于 2015-12-09T13:33:06.713 回答