Webアプリケーションにセキュリティを追加するサーブレットフィルタを作成しました。状況によっては、アプリケーションサーバーとの接続が双方向SSL(TLS 1.0)で行われたことを確認したいと思います。通常、これはHttpServletRequest.getAttribute("javax.servlet.request.X509Certificate")
;を介して行われます。ただし、私の状況では、アプリケーションサーバーの前にリバースプロキシがあり、このプロキシはアプリケーションサーバーにクライアント証明書を経由して渡します。WL-Proxy-Client-Cert
ヘッダ。そのため、前述の属性を取得すると、元々ヘッダーに含まれていたクライアント証明書を取得します。私がやりたいのは、クライアント証明書だけでなく、リバースプロキシとアプリケーションサーバー間の接続が双方向SSLで保護されていることを確認することです。サーブレットからこの検証を行う方法はありますか?WebLogic 10.3.4、Java EE 5を使用しています。同じサーバー上の他の一部のサービスでは一方向SSLしか必要としないため、双方向SSLを要求するようにWebLogicSSLポートを構成することはできません。
3 に答える
を使用してフィルターの元の要求で取得するの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
。
ここでそれらの証明書を確認できますが、そうすることにはほとんど意味がないと思います。これは、ユーザーとプロキシ間の接続が行われるときに、実際にはリバースプロキシ内で行われる必要があります。プロキシを信頼しない場合は、とにかく必要な証明書を送信する可能性があります。ユーザーがワーカーノードからその証明書の秘密鍵を持っているかどうかを確認することはできません。リバースプロキシのみがこれを行うことができます。
そうは言っても、この方法で取得したクライアント証明書を使用して承認を決定することはできます(ここでも、リバースプロキシを信頼している場合、このため、その情報を何らかの方法で送信するリバースプロキシを認証する必要があります)。
クライアント証明書の確認は、クライアントが Web ブラウザーであるかリバース プロキシであるかに関係なく同じです。プロパティを取得し、"javax.servlet.request.X509Certificate"
(DN または発行者に基づいて) リバース プロキシと一致することを確認します。
はWL-Proxy-Client-Cert
、アプリ サーバーに提示された証明書がプロキシのものであることを確認した後、アプリ サーバーがプロキシに提示されたクライアント証明書を知りたい場合にのみ機能します。
双方向SSL認証がない限り、クライアント証明書はありません。証明書の存在は十分な証拠です。