首页 > 解决方案 > 进行身份验证时如何在码头服务器中获取客户端的证书

问题描述

通过设置 SslContextFactory.setNeedClientAuth(true) 设置请求客户端身份验证的嵌入式 Jetty 服务器后,当客户端连接到码头服务器两种情况下,身份验证成功和失败时,如何获取客户端的证书信息?

我已阅读此参考资料,但我认为这仅适用于身份验证成功。SecureRequestCustomizer.customize(...)似乎只有在客户端的证书信息成功验证后才执行。

但是我想知道当码头服务器进行身份验证时,无论成功还是失败,有什么方法可以获取客户端的证书信息。然后我可以得到客户端的证书信息,即使这个客户端不受码头服务器的信任。

标签: ssljettyembedded-jettysslcontext

解决方案


欢迎来到stackoverflow。

设置后,这意味着您SslContextFactory.setNeedClientAuth(true)正在设置 Java 级别javax.net.ssl.SSLParameters.setNeedClientAuth(true)

这会影响新连接的 Java 级别 TLS/SSL 协商,并强制它们需要有效的客户端证书。

如果失败,Java 本身会在 TLS/SSL 握手级别终止连接,客户端甚至不会发送 HTTP 请求,Jetty 也没有参与此确定。

毫无疑问,您已经注意到,TLS/SSL 级别客户端身份验证失败的连接不会在SecureRequestCustomizer.

如果您想查看成功和失败的客户端通过 TLS/SSL 握手级别并到达您的各种 HTTP 处理程序,那么您必须关闭该SslContextFactory.setNeedClientAuth(true)设置。但这意味着 Java JVM 的 TLS/SSL 层不执行客户端证书身份验证,您现在可以在自己的代码中执行这些相同的检查。这不会很好地工作。

所以你可以选择...

  1. setNeedClientAuth(true)- 连接经过身份验证,如果客户端证书失败则终止。客户端没有创建 HTTP 请求。
  2. setNeedClientAuth(false)- 所有连接都成功且不执行身份验证,从而产生您可以处理的 HTTP 请求。

如果您需要第 1 点,但第 2 点不行,请考虑使用org.eclipse.jetty.io.ssl.SslHandshakeListener并只注意成功/失败的结果。

创建您自己的此侦听器实现,并将其作为 bean 添加到您的服务器连接器。您将通过该javax.net.ssl.SSLEngine事件源的活动,您可以在其中询问您在连接失败后的各种详细信息(您甚至可以获取尝试连接的客户端的 IP 信息)


推荐阅读