java - Jetty,isSecure() 在 HTTPS 连接上返回 false

标签 java https jetty embedded-jetty

我遇到了一个问题,isSecure() 在请求到达 HTTPS 连接时返回 false,实际上是一个带有来自公共(public) CA 的有效证书(用户和服务器证书)的 HTTPS 连接。为什么?

这是一个调用堆栈:

callstack

但是 isSecure() 返回的成员为 false:

enter image description here

这是 Jetty 9.4.8 的情况。

更新

HttpChannelOverHttp(HttpChannel).onRequest(MetaData$Request)行:638我看到_request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()) ); 可以将标志设置为 true。不幸的是,URI 的 //host.name:8081/path/a/b/c 格式不完整,并且 getScheme() 返回 null这会导致 is() 返回 false。什么?

更新2

看来我可以通过将以下内容添加到 jetty-config.xml 中的 HttpConfiguration 来解决此问题:

                <Call name="addCustomizer">
                  <Arg>
                      <New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
                  </Arg>
                </Call>

但我不清楚为什么这是必要的以及为什么它不起作用 OOTB。

最佳答案

正如您自己发现的那样,您缺少一个配置。

您认为需要手动添加此配置的事实告诉我您正在使用旧版本的 Jetty。 (请考虑升级,现在更容易控制,如下所示)

SecureRequestCustomizerHttpConfiguration负责处理 SSL 证书、SNI、主机检查、各种 HttpServletRequest 的识别SSL/TLS 等属性。

在旧版本的 Jetty 上看起来像这样。

<Call name="addCustomizer">
  <Arg>
    <New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
  </Arg>
</Call>

在较新版本的 Jetty 上,这是由 jetty-ssl.xml 添加的xml( 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 由另一个进程处理,该进程通过非安全通道(不加密的标准 HTTP)与 Jetty 进行通信、代理、unix 套接字等)。然后,连接是否安全的事实将通过“转发” header 传达给 jetty 。

此转发行为由不同的定制器控制 org.eclipse.jetty.server.ForwardedRequestCustomizer (在 jetty-http-forwarded.xml 中找到,即 http-forwarded 模块的哪一部分)

关于java - Jetty,isSecure() 在 HTTPS 连接上返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49232467/

相关文章:

php - 无法连接到 WSDL

java - 如何创建最小的 spring-boot 可部署 .war 文件?

java - 让 Jetty 正常关闭启动失败的 Web 应用程序上下文

java - 在 SAX 解析器中解析大型 XML 文件时没有内存的异常

java - 将依赖项与我的主 jar 并排复制

http - 代理和记录 http 流量的单行程序?

ruby-on-rails - rails : local server handling SSL

java - Jetty - 检测断开连接的客户端(续)

java - 使用 JPQL 计算关联对象的正确方法

java - 使用 Java 进行 JWT Token 验证