質問

JAX-WS (Metro) を使用して、ユーザー名トークン認証 (パスワード ダイジェスト、ノンス、タイムスタンプ) とタイムスタンプ検証を備えた WS-Security と、SSL 経由の WS-Addressing を使用するスタンドアロン Java Web サービス クライアントを開発しようとしています。

使用する必要がある WSDL には、セキュリティ ポリシー情報が定義されていません。WSDL にこの情報が含まれていない場合に、このヘッダー情報を追加する方法 (正しい方法) を正確に理解できませんでした。Metro を使用して私が見つけたほとんどの例は、Netbeans を使用してこれを WSDL から自動的に生成することを中心に展開していますが、これはまったく役に立ちません。WSIT、XWSSなどを調べました。明確さや方向性があまりありません。JBoss WS Metro もまだあまり運が良さそうにありませんでした。

これを行った経験がある人、またはこのタスクを達成する方法について提案がある人はいますか?正しい方向を示してくれるだけでも役に立ちます。Java ベースである必要があることを除けば、特定のテクノロジに限定されることはありません。

役に立ちましたか?

解決

結局この問題は解決しましたが、別の方向に進みました。私の解決策は、CXF 2.1 とその JAX-WS 実装を使用し、CXF の機能と既に導入されている既存の Spring インフラストラクチャを組み合わせることでした。CXF には多数の jar が必要だったので、最初は懐疑的でしたが、最終的には、CXF が最良かつ最も簡単なソリューションを提供してくれました。

からの例を適応させると、 クライアント構成用の CXF Web サイト, Spring 内でカスタム CXF JAXWS 名前空間を使用し、ユーザー名トークン認証 (パスワード ダイジェスト、ノンス、タイムスタンプ) とタイムスタンプ検証に Out インターセプターを使用しました。これを機能させるための他の唯一の手順は、アウトバウンド SOAP リクエストごとに実行される独自のパスワード コールバック ハンドラーを作成することでした。

SSL設定については、再び次のことに目を向けました。 CXF とコンジットを介した SSL サポート, 、特定の http:conduit 名で SSL を動作させることはできませんでしたが、運用環境では推奨されない汎用のものを使用する必要がありました。

以下は私の設定ファイルの例です。

春の設定ファイル

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:sec="http://cxf.apache.org/configuration/security"
    xmlns:http="http://cxf.apache.org/transports/http/configuration"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cxf="http://cxf.apache.org/core"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
    http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">

    <context:property-placeholder location="meta/my.properties" />
    <context:component-scan base-package="com.foo" />

    <import resource="remoting.xml" />
    <jaxws:client id="myWebService" address="${my.endpointAddress}"
                  serviceClass="com.foo.my.ServicePortType">

<!-- Testing only, adds logging of entire message in and out -->
<jaxws:outInterceptors>
    <ref bean="TimestampUsernameToken_Request" />
    <ref bean="logOutbound" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
        <ref bean="logInbound" />
    </jaxws:inInterceptors>
    <jaxws:inFaultInterceptors>
        <ref bean="logOutbound" />
    </jaxws:inFaultInterceptors>

<!-- Production settings -->
<!--
    <jaxws:outInterceptors> <ref bean="TimestampUsernameToken_Request" />
    </jaxws:outInterceptors>
    -->
</jaxws:client >



<!--
    CXF Interceptors for Inbound and Outbound messages
    Used for logging and adding Username token / Timestamp Security Header to SOAP message
-->
<bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

<bean id="TimestampUsernameToken_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
        <map>
            <entry key="action" value="UsernameToken Timestamp" />
            <entry key="user" value="${my.group}.${my.userId}" />
            <entry key="passwordType" value="PasswordDigest" />
            <entry key="passwordCallbackClass" value="com.foo.my.ClientPasswordHandler" />
        </map>
    </constructor-arg>
</bean>

<!--
    http:conduit namespace is used to configure SSL using keystores, etc
    *.http-conduit works but CXF says its only supposed to be for temporary use (not production),
    well until the correct way works, we're going to use it.
-->
<http:conduit name="*.http-conduit">
    <http:tlsClientParameters   
                  secureSocketProtocol="SSL">
                  <!--
          <sec:trustManagers>
        <sec:keyStore type="JKS"
                         password="${my.truststore.password}"
                         file="${my.truststore.file}" />
                  </sec:trustManagers>
                  -->
                  <sec:keyManagers keyPassword="${my.keystore.password}">
                    <sec:keyStore type="JKS"
                         password="${my.keystore.password}"
                         file="${my.keystore.file}" />
                  </sec:keyManagers>

                  <!-- Cipher suites filters specify the cipher suite to allow/disallow in SSL communcation  -->
                  <sec:cipherSuitesFilter>
                    <sec:include>.*_WITH_3DES_.*</sec:include>
                    <sec:include>.*_EXPORT_.*</sec:include>
                    <sec:include>.*_EXPORT1024_.*</sec:include
                    <sec:include>.*_WITH_DES_.*</sec:include
                    <sec:exclude>.*_WITH_NULL_.*</sec:exclude
                    <sec:exclude>.*_DH_anon_.*</sec:exclude>
                  </sec:cipherSuitesFilter>
    </http:tlsClientParameters>
</http:conduit>
</beans>

Javaクライアントパスワードハンドラ:

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.log4j.Logger;
import org.apache.ws.security.WSPasswordCallback;


/**
 * <p>
 * Provides a callback handler for use processing outbound/inbound SOAP messages.
 * ClientPasswordHandler sets the password used in the WS-Security UsernameToken 
 * SOAP header.
 * 
 * </p>
 * 
 * Created: Apr 1, 2009
 * @author Jared Knipp
 * 
 */
public final class ClientPasswordHandler implements CallbackHandler {
    protected static Logger log = Logger.getLogger(ClientPasswordHandler.class);

    private static final PropertyManager PROPS = PropertyManager.getInstance();
    private static String PASSWORD = PROPS.getPassword();
    private static boolean IS_PASSWORD_CLEAR = PROPS.getIsClearPassword();

    /**
     * Client password handler call back.  This method is used to provide
     * additional outbound (or could be inbound also) message processing.
     * 
     * Here the method sets the password used in the UsernameToken SOAP security header
     * element in the SOAP header of the outbound message.  For our purposes the clear 
     * text password is SHA1 hashed first before it is hashed again along with the nonce and 
     * current timestamp in the security header.
     */
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        if(log.isDebugEnabled()) { log.debug("Setting password for UsernameToken"); }
        WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];


        // Check to see if the password is already Hashed via SHA1, if not then hash it first
        if(IS_PASSWORD_CLEAR) {
            synchronized(this) {
                PASSWORD = PasswordDigestUtil.doPasswordDigest(PASSWORD);
                IS_PASSWORD_CLEAR = false;
                PROPS.setIsClearPassword(IS_PASSWORD_CLEAR);
                PROPS.setPassword(PASSWORD);
                PROPS.saveProperties();
            }
        }

        pc.setPassword(PASSWORD);
    }
}

他のヒント

の情報がWSDLに含まれていない場合、あなたはそれがWSDLで記述されたサービスでありますよろしいですか? WSDLは、サービスを利用するために必要なセキュリティポリシーなどのサービスを記述するために必要なすべての情報を提供するためのものです。

どのようなプラットフォームWSDLから来たのか?それは、WSDLが完全な説明ではないことは可能ですか?例えば、それはを別のWSDLでのDが含まれているWSDLかもしれません。のセキュリティ情報を提供しません。

ポストは、WS-SecurityでクライアントおよびCXFでサーバーを構成する方法を説明ここにあります:<のhref = "http://blog.jeshurun.ca/technology/jax-ws-web-services-with春とCXFする

と「のrel = "nofollowを"> JAX-WS Webサービス-と-CXFを-spring
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top