使用mod_proxy_http 将经过身份验证的用户名从 Apache 转发到 Tomcat 并没有真正的标准方法,但您可以轻松创建一个:
- 配置 Apache 2 以发送
X-Forwarded-User 标头(如果我们有经过身份验证的用户):
RequestHeader unset X-Forwarded-User
RequestHeader set X-Forwarded-User "expr=%{REMOTE_USER}" "expr=-n %{REMOTE_USER}"
- 在 Tomcat 端编译(并将其放入
$CATALINA_BASE/lib)Valve,它将从 “受信任” 主机检索 X-Forwarded-User:
import java.io.IOException;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import org.apache.catalina.connector.CoyotePrincipal;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
public class RemoteUserValve extends ValveBase {
private static String remoteUserHeader = "X-Forwarded-User";
// Same as in RemoteIpValve
private static Pattern internalProxies = Pattern
.compile("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|"
+ "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|"
+ "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|"
+ "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" + "0:0:0:0:0:0:0:1|::1");
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (internalProxies.matcher(request.getRemoteAddr()).matches()) {
final String user = request.getHeader(remoteUserHeader);
if (user != null && !user.isEmpty()) {
request.setUserPrincipal(new CoyotePrincipal(user));
}
}
getNext().invoke(request, response);
}
}
- 将阀门添加到
servers.xml
<Engine name="Catalina">
<Valve className="fully.qualified.name.RemoteUserValve" />
...
</Engine>
我认为这不是很安全,但它提供了与等效 AJP 功能相同级别的安全性。