Frage

Ich versuche, ein eigenständiges Java-Web-Service-Client mit JAX-WS (Metro) zu entwickeln, die verwenden WS-Security mit Benutzername Token-Authentifizierung (Passwort verdaut, Nonces und Zeitstempel) und Zeitstempel Überprüfung zusammen mit WS-Addressing SSL über.

Die WSDL ich mit arbeiten müssen definiert keine Sicherheitspolitik Informationen. Ich habe nicht in der Lage gewesen, genau herauszufinden, wie diese Header-Informationen hinzuzufügen (die richtige Art und Weise zu tun), wenn die WSDL diese Information nicht enthalten. Die meisten Beispiele Ich habe mit Metro um mit Netbeans drehen gefunden, um automatisch diese aus dem WSDL zu erzeugen, die mir überhaupt nicht helfen. Ich habe in WSIT sah, XWSS etc. ohne viel Klarheit oder Richtung. JBoss WS Metro sah noch dort entweder nicht viel Glück versprechen.

Jedermann hat Erfahrung dies zu tun oder haben Vorschläge, wie diese Aufgabe zu erfüllen? Auch zeigt mich in die richtige Richtung wäre hilfreich. Ich bin nicht auf eine bestimmte Technologie andere beschränkt, als es muss Java basiert.

War es hilfreich?

Lösung

Ich habe aus dieser Frage am Ende herauszufinden, aber ich ging in eine andere Richtung zu tun. Meine Lösung war CXF 2.1 und die JAX-WS-Implementierung zu verwenden, die Macht des CXF mit der bestehenden Infrastruktur Frühling kombinierte ich bereits an Ort und Stelle hatte. Ich war wegen der zahlreichen Gläser zunächst skeptisch erforderlich durch CXF, aber am Ende, sofern sie die beste und einfachste Lösung.

Die Anpassung ein Beispiel aus dem CXF Website für die Client-Konfiguration , ich benutzte die benutzerdefinierte CXF JAXWS Namespace innerhalb Frühling und verwendet, um eine Out Interceptor für Benutzername Token-Authentifizierung (Passwort verdauen, Nonces und Zeitstempel) und Zeitstempel Prüfung. Der einzige andere Schritt, um diese Arbeit wurde meine eigenen Passwort Callback-Handler erstellen, die für jede ausgehende SOAP-Anforderung ausgeführt wird.

Für die SSL-Konfiguration, drehte ich mich wieder an CXF und seine SSL-Unterstützung über Leitungen , obwohl ich nie SSL Arbeit mit einem bestimmten http machen könnte. Leitung Namen, ich hatte den allgemeinen Zweck eine verwenden, das nicht für Produktionsumgebungen empfohlen

Im Folgenden ist ein Beispiel für meine Config-Datei.

Frühling config-Datei

<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-Client-Passwort Handler :

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);
    }
}

Andere Tipps

Wenn die Informationen nicht in der WSDL, sind Sie sicher, dass es in dem Dienst durch die WSDL beschrieben? Die WSDL soll alle erforderlichen Informationen bereitzustellen, um den Dienst zu beschreiben, einschließlich der Sicherheitsrichtlinien erforderlich, den Dienst zu nutzen.

Welche Plattform hat die WSDL kommen aus? Ist es möglich, dass der WSDL nicht die vollständige Beschreibung ist? Zum Beispiel könnte es sich um eine WSDL sein, das ist sind d in einer anderen WSDL, dass hat bieten die Sicherheitsinformationen.

Es gibt einen Beitrag hier zu erklären, wie ein Client und einen Server in CXF mit WS-Security konfigurieren: JAX-WS Web Service mit Frühlings- und CXF

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top