进行身份验证时如何在jetty服务器中获取客户端证书

How to get the client's certificate in jetty server when doing authentication

通过设置SslContextFactory.setNeedClientAuth(true)设置了一个请求客户端认证的嵌入式Jetty服务器后,客户端连接到jetty服务器时如何获取客户端的证书信息对于两种情况,认证成功和失败?

我读过这个reference但我认为这只适用于身份验证成功。 SecureRequestCustomizer.customize(...)好像是客户端的证书信息认证成功后才执行的

但是我想知道有没有什么办法可以在jetty server做认证的时候获取客户端的证书信息,不管是成功还是失败。然后我可以得到客户端的证书信息,即使这个客户端不被码头服务器信任。

欢迎使用 Whosebug。

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

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

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

正如您 no-doubt 已经注意到的,未通过 TLS/SSL 级别客户端身份验证的连接不会在 SecureRequestCustomizer 中处理。

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

所以你可以选择...

  1. setNeedClientAuth(true) - 连接已通过身份验证,如果客户端证书失败则终止。客户端未创建任何 HTTP 请求。
  2. setNeedClientAuth(false) - 所有连接均成功,但未执行任何身份验证,从而生成您随后可以处理的 HTTP 请求。

如果您需要点 1,但点 2 是 no-go,请考虑使用 org.eclipse.jetty.io.ssl.SslHandshakeListener 并只关注 success/failure 的结果。

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