2012-09-05 9 views
5

Ich muss einen Authentifizierungsheader (d. H. Als Teil einer SOAP-Headeranforderung) in meinen neuen Webdienst integrieren. Dieser Authentifizierungsheader überprüft die userId- und Kennwortdetails. Ich muss den Inhalt der Anforderungsheaderdetails für die Authentifizierung in meinem Webdienst überprüfen. Wenn authentifiziert wird, wird der SOAP-Text der Anfrage verarbeitet, andernfalls wird eine ungültige Authentifizierungsnachricht vom Web-Service an die Client-Anwendung zurückgesendet, die den Service aufruft.Hinzufügen von Elementen in der SOAP-Header-Anforderung für die Authentifizierung

Ich kann nicht verstehen, wie man einen Webservice erstellt, wo der SOAP-Header einige Elemente enthält (in meinem Fall Authentifizierungselemente wie userId und Passwort).

Normalerweise wird jede Methode, die im Service verfügbar ist, als Teil des SOAP-Body kommen. Daher verwirrt, wie mit dem Hinzufügen von Authentifizierungselementen im SOAP-Header fortfahren.

Bitte helfen

Grüße,

+0

Kann sich jemand das anschauen? https://stackoverflow.com/questions/43002576/soap-header-xmlnsds-on-each-element-for-xml-signature-generation –

Antwort

4

Vor kurzem habe ich eine Klasse geschrieben, die Benutzer-Credentials zu SOAP Header hinzufügt. Dazu müssen Sie eine Klasse erstellen, die die Schnittstelle SOAPHandler<SOAPMessageContext> implementiert. Für z.B .:

public class MyHandler implements SOAPHandler<SOAPMessageContext> { 

    private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class); 

    private String username; 

    private String password; 

    /** 
    * Handles SOAP message. If SOAP header does not already exist, then method will created new SOAP header. The 
    * username and password is added to the header as the credentials to authenticate user. If no user credentials is 
    * specified every call to web service will fail. 
    * 
    * @param context SOAP message context to get SOAP message from 
    * @return true 
    */ 
    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     try { 
      SOAPMessage message = context.getMessage(); 
      SOAPHeader header = message.getSOAPHeader(); 
      SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 
      if (header == null) { 
       header = envelope.addHeader(); 
      } 
      QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials"); 
      SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials); 

      QName qNameUsername = new QName("https://your.target.namespace/", "Username"); 
      SOAPHeaderElement username = header.addHeaderElement(qNameUsername); 
      username.addTextNode(this.username); 
      QName qNamePassword = new QName("https://your.target.namespace/", "Password"); 
      SOAPHeaderElement password = header.addHeaderElement(qNamePassword); 
      password.addTextNode(this.password); 

      userCredentials.addChildElement(username); 
      userCredentials.addChildElement(password); 

      message.saveChanges(); 
      //TODO: remove this writer when the testing is finished 
      StringWriter writer = new StringWriter(); 
      message.writeTo(new StringOutputStream(writer)); 
      LOGGER.debug("SOAP message: \n" + writer.toString()); 
     } catch (SOAPException e) { 
      LOGGER.error("Error occurred while adding credentials to SOAP header.", e); 
     } catch (IOException e) { 
      LOGGER.error("Error occurred while writing message to output stream.", e); 
     } 
     return true; 
    } 

    //TODO: remove this class after testing is finished 
    private static class StringOutputStream extends OutputStream { 

     private StringWriter writer; 

     public StringOutputStream(StringWriter writer) { 
      this.writer = writer; 
     } 

     @Override 
     public void write(int b) throws IOException { 
      writer.write(b); 
     } 
    } 

    @Override 
    public boolean handleFault(SOAPMessageContext context) { 
     LOGGER.debug("handleFault has been invoked."); 
     return true; 
    } 

    @Override 
    public void close(MessageContext context) { 
     LOGGER.debug("close has been invoked."); 
    } 

    @Override 
    public Set<QName> getHeaders() { 
     LOGGER.debug("getHeaders has been invoked."); 
     return null; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

Bitte beachte, dass ich nur die Anmeldeinformationen an den Header bin das Hinzufügen und die Rückkehr true. Sie tun, was immer Sie wollen mit der gesamten Nachricht und false zurückgeben, wenn etwas, das erwartet wird, fehlschlägt.

Ich habe dieser den Client implementiert:

<bean id="soapHandler" class="your.package.MyHandler"> 
    <property name="username" value="testUser"/> 
    <property name="password" value="testPassword"/> 
</bean> 

<jaxws:client "..."> 
    <jaxws:handlers> 
     <ref bean="soapHandler"/> 
    </jaxws:handlers> 
</jaxws:client> 

Es kann aber auch auf der endpoint umgesetzt werden.

+0

Ja, es kommt aus javax.xml.ws.handler.soap-Paket. Ich weiß nicht, ob es mit JAX-RPC funktioniert, ich habe es nur mit JAX-WS benutzt. Sie sollten versuchen, ob es funktioniert :) –

+1

Hier ist der Link, den Sie über JAX-RPC-Handler mit IBM lesen sollten: http://www.ibm.com/developerworks/webservices/library/ws-tipjax2/index.html –

+0

Wenn Sie einen Handler haben und die Nachricht in diesem Handler empfangen können, bedeutet dies, dass Sie alles mit der Nachricht tun können. Sie müssen nur herausfinden, wie Sie die Nachricht des RPC-Stils ändern können. Hier sind die Beispiele, wie es über JAX-RPC gemacht wird: http://www.ibm.com/developerworks/xml/library/ws-tip-extend/index.html –

0

Wir können Header aus dem Umschlag nur nicht von Soap-Nachricht erhalten.