2012-06-12 18 views
46

私は、ブラウザクライアントを持ち、サードパーティとのサーバー間通信に参加している分散アプリケーションのサーバーで作業しています。 私のサーバーには、クライアントがHTTP/SとXMPP(セキュア)を使用したTLS(SSL)通信を使用して接続できるようにするCA署名付き証明書があります。それはすべて正常に動作しています。JAX-WSクライアントのSSLContextをプログラムで設定する方法は?

ここで、HTTPS/SSL経由でJAX-WSを使用して、サードパーティのサーバーに安全に接続する必要があります。この通信では、私のサーバはJAX-WSインターラクションのクライアントとして動作し、第三者が署名したクライアント証明書を持っています。

標準のシステム構成(-Djavax.net.ssl.keyStore=xyz)で新しいキーストアを追加しようとしましたが、私の他のコンポーネントはこれによって明らかに影響を受けます。私の他のコンポーネントはSSL設定(my.xmpp.keystore=xxx, my.xmpp.truststore=xxy, ...)に専用パラメータを使用していますが、最終的にはグローバルSSLContextを使用しているようです。 (構成ネームスペースmy.xmpp.は分離を示すように見えましたが、そうではありません)

クライアント証明書を元のキーストアに追加しようとしましたが、私の他のコンポーネントはそれも気に入らないようです。

私の唯一の選択肢は、JAX-WS HTTPS構成をプログラムでフックして、クライアントJAX-WSの相互作用のためにキーストアとトラストストアをセットアップすることだと思います。

どのようにこれを行うにはどのアイデア/ポインターですか?私が見つけたすべての情報はjavax.net.ssl.keyStoreメソッドを使用しているか、グローバルSSLContextに-Iが同じconfilcで終わってしまうと設定しています。私が何か助けになったのは、私が必要とする機能を要求するこの古いバグレポートでした:Add support for passing an SSLContext to the JAX-WS client runtime

何でもかまいません。

+0

バグレポートによると、修正は2.1.1で利用できるようになります。 – EJP

+0

@EJPバグレポートは機能リクエストであり、どのようにしてやるべきかは言及していません。 – maasg

答えて

47

この1つはクラックするのは難しいナットだったので、記録のために:

これを解決するためには、カスタムKeyManagerと分離KeyStoreにアクセスするには、このカスタムKeyManagerを使用していますSSLSocketFactoryを必要としていました。 how-to-dynamically-select-a-certificate-alias-when-invoking-web-services

そして、特殊SSLSocketFactoryニーズがWebサービスコンテキストに挿入される:

service = getWebServicePort(getWSDLLocation()); 
BindingProvider bindingProvider = (BindingProvider) service; 
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", getCustomSocketFactory()); 

getCustomSocketFactory()SSLSocketFactoryを返し 私はこの優れたブログエントリにこのKeyStoreSSLFactoryの基本コードを発見しました上記の方法で作成されます。これは、SSLSocketFactoryプロパティを示す文字列がこの実装では独自のものであるため、JDKに組み込まれたSun-OracleのimplからのJAX-WS RIに対してのみ機能します。

この段階では、SSLを使用してJAX-WSサービスの通信が保護されますが、同じセキュアサーバー()からWSDLをロードすると、WSDLを収集するHTTPS要求としてブートストラップの問題が発生しますWebサービスと同じ資格情報を使用しません。 (:... ///ファイル)と動的Webサービスのエンドポイントを変更する:私は、WSDLがローカルで利用可能にすることによってこの問題を回避働いていた(これが必要な理由について良い議論がin this forumを見つけることができます)

bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, webServiceLocation); 

これで、WebServiceはブートストラップされ、名前付き(エイリアス)クライアント証明書と相互認証を使用して、SSLを介してサーバーの相手と通信できます。∎

+0

これは、http://の下でWSDLにアクセスできる場合にのみ役立ちますが、https://の下にある場合はどうなりますか?クライアントは最初のステップ(WSDLの取得)に失敗します。 –

+2

私たちは同じ状況を抱え、wsdlのコピーをローカルに持っていました。それ以外の場合は、このブートストラップの問題があります。 – maasg

+0

解決策の解決策について、以下に新しいコメントを追加します。 –

18

これは私がthis postに基づいて解決した方法です。このソリューションでは、追加のクラスを作成する必要はありません。

SSLContext sc = SSLContext.getInstance("SSLv3"); 

KeyManagerFactory kmf = 
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(new FileInputStream(certPath), certPasswd.toCharArray()); 

kmf.init(ks, certPasswd.toCharArray()); 

sc.init(kmf.getKeyManagers(), null, null); 

((BindingProvider) webservicePort).getRequestContext() 
    .put(
     "com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", 
     sc.getSocketFactory()); 
16

私は次のことを試してみました、それは私の環境では動作しませんでした:

bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", getCustomSocketFactory()); 

しかし、異なる特性が魅力のように働いた:

bindingProvider.getRequestContext().put(JAXWSProperties.SSL_SOCKET_FACTORY, getCustomSocketFactory()); 

コードの残りの部分を撮影しました最初の返信から

+0

すべてのバージョンは?異なるバージョンの 'wsimport'が異なる種類のコードを生成するように見えます。異なるプロパティ名を必要とする可能性もあります。 –

+4

明示的にjaxws-rt JARをアプリケーションに追加するときは、 '.internal.'を含まないプロパティ名を使用する必要があります。 JDKに含まれるJAXWS-RTを使用する場合は、 "。internal"を含むものを使用する必要があります。 'JAXWSProperties.SSL_SOCKET_FACTORY'が' 'com.sun.xml.ws.transport.https.client.SSLSocketFactory" 'に解決されました。 –

2

あなたのWSDLにhttps://でもアクセスできない限り、上の内容は問題ありません。ここで

は、このために私の回避策です:デフォルトとしてあなたがのSSLSocketFactory

セット:

私はあなたの設定にこれらの行を追加する必要もあり使いのApache CXFについては
HttpsURLConnection.setDefaultSSLSocketFactory(...); 

<http-conf:conduit name="*.http-conduit"> 
    <http-conf:tlsClientParameters useHttpsURLConnectionDefaultSslSocketFactory="true" /> 
<http-conf:conduit> 
0

これを試してもうまく動かない人には、これはWildfly 8でダイナミックなものを使ってくれました。Dispatcher

bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", yourSslSocketFactory);

プロパティキーからinternal一部がここになくなっていることに注意してください。あなたがhttps後ろWSDLにアクセスすることができラデクとl0coの答えを組み合わせることにより

+0

私はWildfly 8を使用しています。 (動的ディスパッチャー*とはどういう意味ですか? - 私の投稿をチェックしてください:http://stackoverflow.com/questions/37158821/wildfly-how-to-use-jaxws-ri-instead-of-apache-cxf-webservice -client-onlyおよびhttp://stackoverflow.com/questions/37158821/wildfly-how-to-use-jaxws-ri-instead-of-apache-cxf-webservice-client-only – badera

3

SSLContext sc = SSLContext.getInstance("TLS"); 

KeyManagerFactory kmf = KeyManagerFactory 
     .getInstance(KeyManagerFactory.getDefaultAlgorithm()); 

KeyStore ks = KeyStore.getInstance("JKS"); 
ks.load(getClass().getResourceAsStream(keystore), 
     password.toCharArray()); 

kmf.init(ks, password.toCharArray()); 

sc.init(kmf.getKeyManagers(), null, null); 

HttpsURLConnection 
     .setDefaultSSLSocketFactory(sc.getSocketFactory()); 

yourService = new YourService(url); //Handshake should succeed 
+0

'getResourceAsStreamの' keystore'は実行しますか(キーストア)は、証明書ファイルのパスを参照しますか? – swifthorseman

+0

この場合、クラスパス内のパスです。絶対ファイルパスが必要な場合は、getClass()。getResourceAsStream()の代わりにFileを使用してください。 – cidus

0

私は問題トラストマネージャを設定するときに、自己署名証明書を信頼していました。私は、カスタムSSLSocketFactory

SSLContext sslcontext = SSLContexts.custom() 
     .loadKeyMaterial(keyStoreFile, "keystorePassword.toCharArray(), keyPassword.toCharArray()) 
     .loadTrustMaterial(trustStoreFile, "password".toCharArray(), new TrustSelfSignedStrategy()) 
     .build(); 
SSLSocketFactory customSslFactory = sslcontext.getSocketFactory() 
bindingProvider.getRequestContext().put(JAXWSProperties.SSL_SOCKET_FACTORY, customSslFactory); 

loadTrustMaterial方法で引数としてnew TrustSelfSignedStrategy()に渡すを作成するためのApacheのSSLContextsビルダーにHTTPClientを使用しました。

0

私はここの手順を試してみました:問題を修正している、

http://jyotirbhandari.blogspot.com/2011/09/java-error-invalidalgorithmparameterexc.html

をと。私は少し微調整を行いました。私はSystem.getPropertyを使って2つのパラメータを設定しました...

+1

ターゲットサイトに到達できない場合、または永続的にオフラインになる場合に備えて、リンクの最も関連する部分です。 –

関連する問題