2016-05-31 5 views
2

Ich erstelle einen Jax-WS-Client mit Apache CXF. Ich habe Probleme mit der Spring-Cotext-Konfiguration. Alles was ich brauche ist dieser Header auf meine Seife Anfrage hinzuzufügen:wie Sicherheitsheader in Jax-ws Anfrage hinzufügen

<soapenv:Header> 
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
    <wsse:UsernameToken wsu:Id="usernametoken"> 
     <wsse:Username>login</wsse:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>   
    </wsse:UsernameToken> 
    </wsse:Security> 

Ich habe drei Parameter: Username, Passwort, Login.

<jaxws:client id="***" name="***" 
       endpointName="***" 
       serviceName="***" 
       address="***" 
       serviceClass="***" 
       username="***" 
       password="***" 
       xmlns:tns="***"> 
</jaxws:client> 

den obigen Code funktioniert und sendet SOAP-Nachricht, aber ohne Sicherheitskopf! Können Sie mir ein paar Ideen geben, wie Sie diesen Header hinzufügen?

Antwort

3

Mit dieser Konfiguration

<jaxws:client etc...> 
     <jaxws:outInterceptors>  
     <bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> 
      <constructor-arg> 
       <map> 
        <entry key="action" value="UsernameToken"/> 
        <entry key="user" value="login"/> 
        <entry key="passwordType" value="PasswordText"/> 
        <entry key="passwordCallbackRef" value-ref="myPasswordCallback"/> 
       </map> 
      </constructor-arg> 
     </bean> 
     </jaxws:outInterceptors> 
    </jaxws:client> 

    <bean id="myPasswordCallback" class="client.ClientPasswordCallback"/> 

Und diese Klasse das Passwort

public class ClientPasswordCallback implements CallbackHandler { 

    public void handle(Callback[] callbacks) throws IOException, 
      UnsupportedCallbackException { 
     WSPasswordCallback pc = (WSPasswordCallback) callbacks[0]; 

     if ("login".equals(pc.getIdentifier())) { 
      pc.setPassword("thepassword"); 
     } // else {...} - can add more users, access DB, etc. 
    } 
} 

zu verwalten Wenn Sie Java-Code bevorzugen, auch möglich ist,

Client client = ClientProxy.getClient(port); 
Endpoint cxfEndpoint = client.getEndpoint(); 
Map<String,Object> outProps = new HashMap<String,Object>(); 
outProps.put("action", "UsernameToken"); 
outProps.put("user", "login"); 
outProps.put("passwordType","PasswordText"); 
ClientPasswordCallback c = new ClientPasswordCallback(); 
outProps.put("passwordCallbackRef",c); 

WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); 
cxfEndpoint.getOutInterceptors().add(wssOut); 
+0

Hallo, warum müssen wir den Benutzer überprüfen? Ist dieser Code für die Client-Seite? Sieht aus wie dieser Code für die Serverseite. Ich konfiguriere keinen Endpunkt, ich möchte nur einen Sicherheitsheader hinzufügen und die Soap-Anfrage senden – rastaman

+0

Dieser Code ist für Client-Seite (siehe das Jax-ws: Client-Tag). Ein Out-Interceptor fängt die Ausgabe ab, bevor sie gesendet wurde, um den Header hinzuzufügen. Wenn Sie die Spring-Konfiguration nicht mögen, verwenden Sie das letzte Java-Beispiel. Vielleicht haben Sie die Methode zur Angabe des Passworts seltsam gefunden, aber es ist die Standardeinstellung für CXF – pedrofb

2

Sie müssen den Sicherheitsheader mit einem CXF-Interceptor hinzufügen.

Sie müssen also im Grunde eine neue Abfangjäger Bohne (WSS4JOutInterceptor von cxf-Sicherheit) und geben Sie die richtigen Schlüsselwerte als Eingabe an den Konstruktor definieren:

<bean id="fooSecurityOutInterceptor" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"> 
    <constructor-arg> 
     <map> 
     [...] 
     </map> 
    </constructor-arg> 
</bean> 

Beachten Sie, dass dies bei http://cxf.apache.org/docs/ws-security.html dokumentiert ist, aber sie kann Sie möchten den Quellcode von org.apache.ws.security.handler.WSHandlerConstants für alle möglichen Schlüssel anzeigen (in Ihrem Fall sehen Sie USERNAME_TOKEN, PASSWORD_TYPE ...) und injizieren Sie Ihre Werte in die entsprechenden Schlüssel in dieser Bean.

Dann weisen Sie diese Bean einfach als Out-Interceptor Ihrer jaxws-Client-Bean zu.

<jaxws:client id="***" name="***" endpointName="***" serviceName="***" address="***" serviceClass="***" xmlns:tns="***"> 
    <jaxws:outInterceptors> 
     <ref bean="fooSecurityOutInterceptor" /> 
    </jaxws:outInterceptors> 
</jaxws:client> 

Das sollte den Trick tun. Sie können einen zweiten Interceptor wie org.apache.cxf.interceptor.LoggingOutInterceptor hinzufügen, um zu überprüfen, ob Ihre Kopfzeile hinzugefügt wird, um die Schlüssel/Werte etwas zu optimieren.

+0

Hallo. Danke für deine Antwort. Nun, ich habe eine Klasse gefunden: UsernameTokenInterceptor es wird mein Problem lösen. Wie könnte ich es im Frühling hinzufügen? – rastaman

Verwandte Themen