ssl - 进行身份验证时如何在码头服务器中获取客户端的证书
问题描述
通过设置 SslContextFactory.setNeedClientAuth(true) 设置请求客户端身份验证的嵌入式 Jetty 服务器后,当客户端连接到码头服务器两种情况下,身份验证成功和失败时,如何获取客户端的证书信息?
我已阅读此参考资料,但我认为这仅适用于身份验证成功。SecureRequestCustomizer.customize(...)
似乎只有在客户端的证书信息成功验证后才执行。
但是我想知道当码头服务器进行身份验证时,无论成功还是失败,有什么方法可以获取客户端的证书信息。然后我可以得到客户端的证书信息,即使这个客户端不受码头服务器的信任。
解决方案
欢迎来到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 层不执行客户端证书身份验证,您现在可以在自己的代码中执行这些相同的检查。这不会很好地工作。
所以你可以选择...
setNeedClientAuth(true)
- 连接经过身份验证,如果客户端证书失败则终止。客户端没有创建 HTTP 请求。setNeedClientAuth(false)
- 所有连接都成功且不执行身份验证,从而产生您可以处理的 HTTP 请求。
如果您需要第 1 点,但第 2 点不行,请考虑使用org.eclipse.jetty.io.ssl.SslHandshakeListener
并只注意成功/失败的结果。
创建您自己的此侦听器实现,并将其作为 bean 添加到您的服务器连接器。您将通过该javax.net.ssl.SSLEngine
事件源的活动,您可以在其中询问您在连接失败后的各种详细信息(您甚至可以获取尝试连接的客户端的 IP 信息)
推荐阅读
- c++ - 如何在预编译后通过查看文件来调试 Boost?
- go - 使用 [][]int 切片越界,但适用于 map[int][]int
- mysql - 我想出了这个 SQL 结构来允许回滚和审计用户信息,这样就足够了吗?
- java - API数据以编码格式出现,如何在java中解码
- android - android.view.InflateException: Binary XML file line #54: Error inflating class EditText
- laravel - Laravel 将自定义中间件添加到路由组
- ios - 使用 Swagger API 的架构 x86_64 的未定义符号:
- ruby-on-rails - 在 Dokku 的移动设备上上传回形针照片 (S3) 时出错
- c# - 声明委托类型以匹配方法签名
- java - Eclipse Windowbuilder 不兼容的 Java