Java からの .NET Web サービス (WSE 2/3、WS-Security) の呼び出し
-
08-06-2019 - |
質問
.NET で書かれた Web サービスを Java から呼び出す必要があります。Web サービスは WS-Security スタック (WSE 2 または WSE 3 のいずれか、私が持っている情報からは明らかではありません) を実装しています。
サービス プロバイダーから受け取った情報には、WSDL、policyCache.config ファイル、いくつかのサンプル C# コード、およびサービスを正常に呼び出すことができるサンプル アプリケーションが含まれていました。
Java クライアントを作成するためにこの情報をどのように使用するかが明確ではないため、これは思っているほど役に立ちません。Web サービス リクエストがポリシーに従って署名されていない場合、そのリクエストはサービスによって拒否されます。Apache Axis2 を使用しようとしていますが、policyCahce.config ファイルと WSDL を使用してクライアントを生成する方法についての手順が見つかりません。
Web 上で見つけた例がいくつかありますが、いずれの場合も、例の作成者はサービスとクライアントの両方を制御していたので、サービスを機能させるために両方の側で調整を加えることができました。私はその立場ではありません。
これを成功させた人はいますか?
解決 2
これはよくある質問のようですので、私たちの状況で行ったことの概要を説明します。
.NET に組み込まれたサービスは、古い ws-addressing 標準 (http://schemas.xmlsoap.org/ws/2004/03/addressing/)、axis2 は新しい標準 (http://schemas.xmlsoap.org/ws/2004/08/addressing/).
さらに、提供されるpolicyCache.configファイルはaxis2 Rampartモジュールが理解できない形式になっています。
したがって、私たちがしなければならなかった手順を簡単に言うと、次のようになります。
- policyCache.config を読んで理解してください。次に、それを Rampart が理解できるポリシーに書き直します。(いくつかの 更新されたドキュメント 助かりました。)
- このポリシーを使用して城壁を構成します。
- .pfx ファイルで提供されたキーを取得し、Java キー ストアに変換します。それを行うことができる Jetty に付属のユーティリティがあります。
- そのキー ストアを使用して Rampart を構成します。
- axis2 から出てくる新しい ws-addressing のものを、サービスが期待する古いものに逆変換するカスタム axis2 ハンドラーを作成します。
- 送信メッセージでハンドラーを使用するように axis2 を構成します。
最終的には、ベンダーがサポートするオープンスタンダードであるはずのもののための、多くの設定とコードが必要になりました。
代替手段が何かはわかりませんが、ベンダー (この場合は 1 つのベンダー) がすべての相互運用性を確認するまで待ってもらえますか?
追記として、その仕事を最終的に私がやったわけではなく、チームの他の誰かがやったことを付け加えておきますが、重要な詳細は正しく理解できたと思います。(チームメイトが引き継ぐ前に) 私が検討していたもう 1 つのオプションは、WSS4J API を直接呼び出して、.NET サービスが期待する SOAP エンベロープを構築することでした。それもうまくいったと思います。
他のヒント
WS-Security 仕様は通常、WSDL には含まれません (WSE WSDL には含まれません)。したがって、wsdl2java は、このサービスに WS-Security が必要であることさえ認識しません。WSE WSDL にセキュリティ制約が存在しないという事実は、私にとっては大きな失望です (WCF では WS-Trust 情報が WSDL に含まれます)。
クライアント側では、次を使用する必要があります 城壁 必要な WS-Security ヘッダーを送信クライアント メッセージに追加します。WSDL では必要な WS-Security 設定が報告されないため、何が必要かをサービス プロバイダーに問い合わせるのが最善です。WS-Security の要件は、単純な平文パスワード、X509 証明書、または暗号化されたメッセージである可能性があります。Rampart は、これらのシナリオのほとんどを処理できるはずです。
Apache Rampart は、axis2.xml ファイルにモジュールを組み込むことで「オン」になります。Rampart モジュールをダウンロードして、axis2 ディレクトリの特定の場所に配置してから、xml ファイルを変更する必要があります。Rampart をプログラム的に利用することもできます (これが要件である場合は、元の質問を編集してください。この回答は編集させていただきます)。
ランパートの構成方法 (他の XML ファイルまたはプログラムによる) に応じて、送信メッセージをインターセプトし、必要な WS-Security 情報をそれに追加します。私は個人的に、axis2 を Rampart とともに使用して、プレーンテキストの UsernameToken で保護された WSE3 サービスを呼び出しましたが、うまく機能しました。同様の、より高度なシナリオも機能するはずです。Rampart をセットアップして開始する方法の詳細については、上記のリンク先のサイトに記載されています。Rampart の詳細、または特定の WSE セットアップで Rampart を使用する方法について問題がある場合は、質問を編集してください。最善を尽くして回答いたします。
@マイク
最近テストを行ったので、これが私が使用したコードです。ポリシーのものは使用していませんが、平文認証で WS-Security を使用しました。CXF には、これを実現する方法に関する非常に優れたドキュメントがあります。
wsdl2java を使用し、ws-security で Web サービスを使用するためにこのコードを追加しました。
これがお役に立てば幸いです。
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.handler.WSHandlerConstants;
public class ServiceTest implements CallbackHandler
{
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
// set the password for our message.
pc.setPassword("buddah");
}
public static void main(String[] args){
PatientServiceImplService locator = new PatientServiceImplService();
PatientService service = locator.getPatientServiceImplPort();
org.apache.cxf.endpoint.Client client = org.apache.cxf.frontend.ClientProxy.getClient(service);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
Map<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN + " " + WSHandlerConstants.TIMESTAMP);
outProps.put(WSHandlerConstants.USER, "joe");
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
// Callback used to retrieve password for given user.
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ServiceTest.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
try
{
List list = service.getInpatientCensus();
for(Patient p : list){
System.out.println(p.getFirstName() + " " + p.getLastName());
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- Apache Axis は WSDL からプロキシ コードを生成できます http://ws.apache.org/axis/java/user-guide.html#UsingWSDLWithAxis
- NetBeans と RESTful Web サービス プラグインを使用すると、コードを生成できます。eBay ショッピング Web サービスのサンプル クライアントの手順は、次の場所にあります。 http://ebay.custhelp.com/cgi-bin/ebay.cfg/php/enduser/std_adp.php?p_faqid=1230.
CXF -CXFを検討してみます。私はこれを使用して、ws-securityを使用してJavaでWebサービスとクライアントを作成しました。.net Web サービスも接続しました。
かなり充実したドキュメントも用意されています。軸よりも運が良かったです。