gpt4 book ai didi

tomcat - 删除 Tuckey url 重写中的基本身份验证 header

转载 作者:行者123 更新时间:2023-11-28 23:27:29 31 4
gpt4 key购买 nike

我有一个安装了 Tuckey 的 Tomcat 服务器作为代理,用于将请求转发到具有嵌入式 Jetty 服务器的应用程序。带有嵌入式 Jetty 的应用程序公开了一个 REST url 但不提供授权。因此,我需要区分对管理 url 和非管理 url 的请求。在 Tomcat 内部,我创建了一个名为“myapp”的应用程序,其中包含一个用于 Tuckey 的过滤器。这是当前的 urlrewrite.xml:

<?xml version="1.0" encoding="UTF-8"?>
<urlrewrite>
<rule match-type="regex">
<note>Allow all these requests</note>
<from>^/v1/api/(one|two|three)/(.*)$</from>
<to type="proxy" encode="false">http://admin-user:admin-password@localhost:8091/myapp/v1/api/$1/${escapePath:UTF-8:$2}</to>
</rule>
<rule match-type="regex">
<note>These requests must be authorised</note>
<from>^/v1/api/(four|five|six)(.*)$</from>
<to type="proxy" encode="false">http://localhost:8091/myapp/v1/api/$1${escapePath:UTF-8:$2}</to>
</rule>
</urlrewrite>

这通常有效 - 除非用户向第一条规则发送不必要的用户凭据。在这种情况下,来自用户的基本身份验证请求被转发到 Jetty,导致未经授权的响应。如果用户可以简单地省略用户名和密码(不幸的是,这并不总是可能的,因为这种行为可能是由客户端的逻辑强制执行的)那么这就不会发生并且请求会顺利通过。

有什么解决办法吗?我可以在 Tuckey 中以某种方式删除基本身份验证 header 吗? set 命令显然不允许设置 auth-type 或类似的。

最佳答案

最后,一位同事帮助我完成了这项工作。

urlrewrite.xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<urlrewrite>
<rule match-type="regex">
<note>Allow all these requests</note>
<from>^/v1/api/(one|two|three)/(.*)$</from>
<to type="proxy" encode="false">http://admin-user:admin-password@localhost:8091/myapp/v1/api/$1/${escapePath:UTF-8:$2}</to>
</rule>
<rule match-type="regex">
<note>These requests must be authorised</note>
<from>^/v1/api/(four|five|six)(.*)$</from>
<to type="proxy" encode="false">http://localhost:8091/myapp/v1/api/$1${escapePath:UTF-8:$2}</to>
</rule>
</urlrewrite>

如您所见,“公共(public)”和“私有(private)”REST URL 有两种不同类型的 URL。对于私有(private) URL,一切正常,它只是转发到我在 8091 运行的本地 Jetty 服务器。对于公共(public) URL,用户名和密码被注入(inject)到 URL 中。如果有人不提供用户名和密码,这就可以正常工作。然而,如果有人确实提供了它们,会发生什么?不幸的是,在这种情况下,仍然会在 Jetty 中触发授权,结果失败(除非用户名和密码是管理员)。这(还)不是我们想要的。

解决方案是从原始请求中删除授权 header 。在类 org.tuckey.web.filters.urlrewrite.RequestProxy 中有方法 setupProxyRequest(HttpServletRequest, URL)。请注意在 while 循环中添加的 else if block 在某些情况下会丢弃授权 header 。

private static HttpMethod setupProxyRequest(final HttpServletRequest hsRequest, final URL targetUrl) throws IOException {
final String methodName = hsRequest.getMethod();
final HttpMethod method;
if ("POST".equalsIgnoreCase(methodName)) {
PostMethod postMethod = new PostMethod();
InputStreamRequestEntity inputStreamRequestEntity = new InputStreamRequestEntity(hsRequest.getInputStream());
postMethod.setRequestEntity(inputStreamRequestEntity);
method = postMethod;
} else if ("GET".equalsIgnoreCase(methodName)) {
method = new GetMethod();
} else {
log.warn("Unsupported HTTP method requested: " + hsRequest.getMethod());
return null;
}

method.setFollowRedirects(false);
method.setPath(targetUrl.getPath());
method.setQueryString(targetUrl.getQuery());

String userInfo = targetUrl.getUserInfo();

Enumeration e = hsRequest.getHeaderNames();
if (e != null) {
while (e.hasMoreElements()) {
String headerName = (String) e.nextElement();
if(headerName != null) headerName = headerName.trim();
if ("host".equalsIgnoreCase(headerName)) {
//the host value is set by the http client
continue;
} else if ("content-length".equalsIgnoreCase(headerName)) {
//the content-length is managed by the http client
continue;
} else if ("accept-encoding".equalsIgnoreCase(headerName)) {
//the accepted encoding should only be those accepted by the http client.
//The response stream should (afaik) be deflated. If our http client does not support
//gzip then the response can not be unzipped and is delivered wrong.
continue;
} else if (headerName.toLowerCase().startsWith("cookie")) {
//fixme : don't set any cookies in the proxied request, this needs a cleaner solution
continue;
}
else if (headerName.toLowerCase().contains("authorization") && userInfo != null) {
// Removed authorization header when userInfo is present
continue;
}

Enumeration values = hsRequest.getHeaders(headerName);
while (values.hasMoreElements()) {
String headerValue = (String) values.nextElement();
log.info("setting proxy request parameter:" + headerName + ", value: " + headerValue);
method.addRequestHeader(headerName, headerValue);
}
}
}
if (userInfo != null) {
String headerValue = "Basic " + new String(Base64.encodeBase64(userInfo.getBytes()));
if ( log.isInfoEnabled()) log.info("setting proxy request parameter: Authorization, value: " + headerValue);
method.addRequestHeader("Authorization", headerValue);
}
if ( log.isInfoEnabled() ) log.info("proxy query string " + method.getQueryString());
return method;
}

web.xml 如下所示:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>URL Rewriting proxy</display-name>
<servlet>
<servlet-name>default</servlet-name>
<!-- Standard Tomcat default servlet -->
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<!-- Standard Tuckey default UrlRewriteFilter class -->
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
</web-app>

关于tomcat - 删除 Tuckey url 重写中的基本身份验证 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35102231/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com