我编写了一个servlet过滤器来为Web应用程序添加安全性。在某些情况下,我想验证与应用程序服务器的连接是否使用双向SSL(TLS 1.0)。通常这是通过HttpServletRequest.getAttribute("javax.servlet.request.X509Certificate")
完成的;但是,在我的情况下,应用程序服务器前面有一个反向代理,这个代理通过WL-Proxy-Client-Cert
标头将应用程序服务器传递给客户端证书。因此,当我检索上述属性时,我得到最初出现在标题中的客户端证书。我想要做的不仅是验证客户端证书,还要确保反向代理和应用程序服务器之间的连接是通过双向SSL保护的。有没有办法让我从servlet进行验证?我正在使用WebLogic 10.3.4,Java EE 5.配置WebLogic SSL端口以要求双向SSL不是一种选择,因为同一服务器上的某些其他服务只需要单向SSL。
答案 0 :(得分:0)
无论客户端是Web浏览器还是反向代理,检查客户端证书都是相同的。只需获取"javax.servlet.request.X509Certificate"
属性并检查它是否与您的反向代理匹配(基于DN或颁发者)。
在验证提交给应用服务器的证书是代理服务器后,当应用服务器想知道向代理提供了哪些客户端证书时,WL-Proxy-Client-Cert
才会发挥作用。
答案 1 :(得分:0)
使用HttpServletRequest.getAttribute("javax.servlet.request.X509Certificate")
在过滤器中的原始请求中获得的是应用程序服务器看到的证书:这将是反向代理自己的客户端证书,如果它使用的话。
根据您的要求,您可以根据需要根据此属性做出与授权相关的决策。您不需要验证您是否信任证书本身,因为身份验证应该由应用程序服务器的SSL连接器(配置适当的信任存储区)完成。
容器中的大多数应用程序可能希望getAttribute("javax.servlet.request.X509Certificate")
引用用户的证书,而不是代理的证书。
您不清楚以哪种格式获取WL-Proxy-Client-Cert
附加标头的值,但我会假设某种PEM格式。
您应该能够转换此内容并将其放入过滤器中的javax.servlet.request.X509Certificate
属性,然后再触及其余的过滤器/逻辑。这应该是表示证书链的java.security.cert.X509Certificate
数组(首先是客户端证书,然后是颁发者)。您可以使用CertificateFactory
(参见示例)或BouncyCastle的PEMReader
进行转换。
您可以在那里验证这些证书,但我会说这样做没什么意义。当用户和代理之间的连接完成时,这应该在反向代理中完成。如果您不信任代理,它可以向您发送它想要的任何证书:您将无法从工作节点检查用户是否具有该证书的私钥,只有反向代理可以执行此操作。
话虽如此,您当然可以使用以这种方式获得的客户端证书来做出授权决策(同样,只要您信任反向代理:因此,您必须对发送给您的反向代理进行身份验证信息这样或那样)。
答案 2 :(得分:-1)
除非有双向SSL身份验证,否则 不会客户端证书。证书的存在就足够了。