有人知道如何从用户会话中删除SSL证书并强制SSL握手再次完成吗?
我已尝试通过调用
删除证书request.removeAttribute("javax.servlet.request.X509Certificate");
但这似乎不起作用。事实上,代码似乎忽略了这个属性。
获取证书的代码最终调用org.apache.tomcat.util.net.jsse.JSSESupport.getPeerCertificateChain(...)
。但是,只有当证书尚未与会话关联时,才会触发重新协商:
if(jsseCerts.length <= 0 && force) {
session.invalidate();
handShake();
session = ssl.getSession();
}
因此,由于您已经拥有SSLSession
的证书(并且由于从请求中删除该属性将对此没有影响),因此您将无法触发将使您忘记该证书的重新协商。
您可能会发现需要修补Tomcat中各种类(调用getPeerCertificateChain
)的实现来实现这一点。如果您想执行"SSL注销"(这是类似的),就需要这样做。您可以通过使用Connection: close
HTTP头请求客户端关闭连接(从而创建一个新的连接,它将在没有客户端证书的情况下进行协商)。然而,由于它通常由关闭方发送,因此不能保证接收方(客户端)将关闭它(而且,据我所知,Servlet规范和Tomcat实现中都没有任何内容允许使用强制关闭连接)。
这是两个不同的问题。
-
该属性仅供servlet和过滤器使用。Tomcat不使用它,事实上,一旦SSL会话存在并且身份验证成功,它并不真正关心证书。你可以删除这个属性但是你只是在欺骗自己,
-
如果您可以使SSL会话无效并请求新的握手,那么无论如何都会传递一个新证书,可能是同一个证书,除非在此期间浏览器证书发生了一些事情。这将覆盖请求属性,因此您实际上不需要首先清除它。但是,我不知道有什么方法可以在Tomcat中使SSL会话无效或重新握手,除非提供您自己的SSL连接器,并提供servlet或过滤器可以访问的API,而且我也不知道如何做到这一点。
你可以随时告诉我们你的要求