Jetty,isSecure() 在 HTTPS 连接上返回 false
Jetty, isSecure() returning false on HTTPS connection
我遇到了一个问题,isSecure()
在请求到达 HTTPS 连接时返回 false,实际上是一个 HTTPS 连接,带有来自公共 CA 的有效证书,包括用户和服务器证书。为什么?
这是一个调用堆栈:
但是isSecure()
返回的成员是假的:
这是 Jetty 9.4.8。
更新
在 HttpChannelOverHttp(HttpChannel).onRequest(MetaData$Request) line: 638
上,我看到 _request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()));
可以将标志设置为 true。不幸的是,URI 不完整 //host.name:8081/path/a/b/c
格式和 getScheme()
returns null
导致 false
被 is()
返回。什么?
更新 2
看来我可以通过将以下内容添加到 jetty-config.xml
中的 HttpConfiguration
来解决此问题:
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
但我不清楚为什么这是必要的以及为什么它在 OOTB 中不起作用。
正如您自己发现的那样,您缺少配置。
您觉得需要手动添加此配置这一事实告诉我您使用的是旧版本的 Jetty。 (请考虑升级,现在更容易控制,如下所示)
HttpConfiguration
中的 SecureRequestCustomizer
负责处理 SSL 证书的识别、SNI、主机检查、SSL/TLS 的各种 HttpServletRequest
属性等。 .
在旧版本的 Jetty 上看起来像这样。
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
在较新版本的 Jetty 上,这是由 jetty-ssl.xml
xml (part of the ssl
模块添加的),看起来像这样...
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- [snip] ssl connector setup -->
<!-- =========================================================== -->
<!-- Create a TLS specific HttpConfiguration based on the -->
<!-- common HttpConfiguration defined in jetty.xml -->
<!-- Add a SecureRequestCustomizer to extract certificate and -->
<!-- session information -->
<!-- =========================================================== -->
<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg><Ref refid="httpConfig"/></Arg>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<Arg name="sniHostCheck" type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg>
<Arg name="stsMaxAgeSeconds" type="int"><Property name="jetty.ssl.stsMaxAgeSeconds" default="-1"/></Arg>
<Arg name="stsIncludeSubdomains" type="boolean"><Property name="jetty.ssl.stsIncludeSubdomains" default="false"/></Arg>
</New>
</Arg>
</Call>
</New>
</Configure>
默认情况下未启用的原因是,如果 Jetty 不处理实际的 SSL/TLS,则可以认为请求是安全的。这是转发场景,来自负载均衡器、代理、防火墙、网关等...在该场景中,SSL/TLS 由另一个进程处理,该进程通过 non-secure 通道与 Jetty 通信(没有加密、代理、unix 套接字等的标准 HTTP)。然后通过 "forwarded" headers 将连接是否安全的事实传达给码头。
此转发行为由不同的定制程序控制 org.eclipse.jetty.server.ForwardedRequestCustomizer
(在 jetty-http-forwarded.xml
, which part of the http-forwarded
模块中找到)
我遇到了一个问题,isSecure()
在请求到达 HTTPS 连接时返回 false,实际上是一个 HTTPS 连接,带有来自公共 CA 的有效证书,包括用户和服务器证书。为什么?
这是一个调用堆栈:
但是isSecure()
返回的成员是假的:
这是 Jetty 9.4.8。
更新
在 HttpChannelOverHttp(HttpChannel).onRequest(MetaData$Request) line: 638
上,我看到 _request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()));
可以将标志设置为 true。不幸的是,URI 不完整 //host.name:8081/path/a/b/c
格式和 getScheme()
returns null
导致 false
被 is()
返回。什么?
更新 2
看来我可以通过将以下内容添加到 jetty-config.xml
中的 HttpConfiguration
来解决此问题:
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
但我不清楚为什么这是必要的以及为什么它在 OOTB 中不起作用。
正如您自己发现的那样,您缺少配置。
您觉得需要手动添加此配置这一事实告诉我您使用的是旧版本的 Jetty。 (请考虑升级,现在更容易控制,如下所示)
HttpConfiguration
中的 SecureRequestCustomizer
负责处理 SSL 证书的识别、SNI、主机检查、SSL/TLS 的各种 HttpServletRequest
属性等。 .
在旧版本的 Jetty 上看起来像这样。
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
在较新版本的 Jetty 上,这是由 jetty-ssl.xml
xml (part of the ssl
模块添加的),看起来像这样...
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- [snip] ssl connector setup -->
<!-- =========================================================== -->
<!-- Create a TLS specific HttpConfiguration based on the -->
<!-- common HttpConfiguration defined in jetty.xml -->
<!-- Add a SecureRequestCustomizer to extract certificate and -->
<!-- session information -->
<!-- =========================================================== -->
<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Arg><Ref refid="httpConfig"/></Arg>
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer">
<Arg name="sniHostCheck" type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg>
<Arg name="stsMaxAgeSeconds" type="int"><Property name="jetty.ssl.stsMaxAgeSeconds" default="-1"/></Arg>
<Arg name="stsIncludeSubdomains" type="boolean"><Property name="jetty.ssl.stsIncludeSubdomains" default="false"/></Arg>
</New>
</Arg>
</Call>
</New>
</Configure>
默认情况下未启用的原因是,如果 Jetty 不处理实际的 SSL/TLS,则可以认为请求是安全的。这是转发场景,来自负载均衡器、代理、防火墙、网关等...在该场景中,SSL/TLS 由另一个进程处理,该进程通过 non-secure 通道与 Jetty 通信(没有加密、代理、unix 套接字等的标准 HTTP)。然后通过 "forwarded" headers 将连接是否安全的事实传达给码头。
此转发行为由不同的定制程序控制 org.eclipse.jetty.server.ForwardedRequestCustomizer
(在 jetty-http-forwarded.xml
, which part of the http-forwarded
模块中找到)