Web Services SOAP in Java

I Web Service (in italiano Servizi Web) hanno un ruolo importante nell’architettura dei software moderni del web.  La diffusione esplosiva del web ha portato alla creazione di una grande quantità di infrastrutture di rete e server, e un Web Services sono software sviluppati appunto per facilitare l’interazione tra macchine tramite la rete, quindi tra macchine non tra umani.

Un client (desktop, web, mobili o embedded)  invia la richiesta su Internet e un server riceve la richiesta, la elabora e restituisce una risposta.  

Una caratteristica molto importante è che il client può essere scritto in qualsiasi linguaggio di programmazione (java, ASP, etc). Stessa cosa vale per il web service.

Questo perché i dati vengono scambiati in un formato comune a tutte le tecnologie: il client non sa come funziona il server e viceversa, ma entrambi lavorano insieme attraverso un vocabolario comune.

Leggi tutto “Web Services SOAP in Java”

Esempio di WebServices con Annotation – Client SOAPUI

Per creare un Web Services esistono vari modi.
In questo esempio useremo l’annotation @WebService. In particolare avremo un web services con due operazioni:

  • public String prova(String msg)
  • public Persona getPerson(String codFisc)

Il primo prende in input una stringa e restituisce un’altra stringa.
Il secondo in input  sempre una stringa ma restituisce un oggetto di tipo Persona.
Per invocarli useremo il tool SOAPUI.

Tools Usati

  • Eclipse Mars 2
  • Wildfly 10
  • SoapUI

Leggi tutto “Esempio di WebServices con Annotation – Client SOAPUI”

Linux – Chiamare un Web Service da riga di comando

invocare un WebService da shell

In genere per chiamare un webservice si usano IDE tipo SOAPUI, ma non sempre si ha a disposizione questa opzione. Spesso dobbiamo testarlo in remoto direttamente dalla shell di linux. Per fare questo, con relativa request e response, si può usare il  comando curl. Di seguito un esempio:

curl –header  “Content-type: text/xml;charset=UTF-8”  –data @requestSOS.xml http://prova:8080/provaWS

viene invocato il webservice  http://prova:8080/provaWS con la request nel file requestSOS.xml

 

Creazione Manuale tag Header SOAP

Questo codice

    Element Security = document.createElementNS(“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”,”wsse:BinarySecurityToken“);
      Security.setAttribute(“EncodingType”, “http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”);

    Security.setAttribute(“ValueType”, “http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3”);
    Security.setAttribute(“wsu:Id”, “token-17-1430806478532-4942389”);

    Security.setTextContent(“fdfdd”);

genera questo tag

<wsse:BinarySecurityToken
EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”
ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3″
wsu:Id=”X509-BFFE0959757C1B436314337783399662″>fdfdd</wsse:BinarySecurityToken>

Stampare una request SOAP

1° Metodo:

  public void printNode(Node allNode) throws TransformerException {
    System.out.println(“——————————-“);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, “yes”);
    StringWriter outWriter = new StringWriter();
    // transformer.transform(new DOMSource(root), new StreamResult(outWriter));
    transformer.transform(new DOMSource(allNode), new StreamResult(System.out));
    System.out.println(“——————————-“);
  }

2° Metodo
    System.setProperty(“com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump”, “true”);
    System.setProperty(“com.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump”, “true”);
    System.setProperty(“com.sun.xml.ws.transport.http.HttpAdapter.dump”, “true”);
    System.setProperty(“com.sun.xml.internal.ws.transport.http.HttpAdapter.dump”, “true”);

Cifrare una request SOAP con BinarySecurityToken

Importare il jar  wss4j   versione  2.2.1 (ultima versione al momento)

<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-bindings</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-integration</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-ws-security-common</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.wss4j</groupId>
<artifactId>wss4j-ws-security-dom</artifactId>
<version>2.1.1</version>
</dependency>

Creare un Handle:

WSSUsernameTokenSecurityHandler .java

package it;

import java.io.FileInputStream;
import java.io.StringWriter;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.message.WSSecHeader;
import org.apache.wss4j.dom.message.WSSecSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class WSSUsernameTokenSecurityHandler implements SOAPHandler<SOAPMessageContext> {


  @Override
  public Set<QName> getHeaders() {
      final QName securityHeader = new QName(
          “http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”,
          “Security”,
          “wsse”);

      final HashSet<QName> headers = new HashSet<QName>();
      headers.add(securityHeader);

      return headers;
  }


  public boolean handleMessage(SOAPMessageContext smc) {
    Boolean outboundProperty = (Boolean)      smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    SOAPMessage message = smc.getMessage();

    
    if (outboundProperty) {
      try {
        SOAPPart soapPart = message.getSOAPPart();

        SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
      
        SOAPHeader header2 = envelope.addHeader();
        
        Source source = soapPart.getContent();

        Node root = null;
        Document doc = null;
        if (source instanceof DOMSource) {
          root = ((DOMSource) source).getNode();
        }
        else if (source instanceof SAXSource) {
          InputSource inSource = ((SAXSource) source).getInputSource();
          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
          dbf.setNamespaceAware(true);
          DocumentBuilder db = null;

          db = dbf.newDocumentBuilder();

          doc = db.parse(inSource);
          root = (Node) doc.getDocumentElement();
        }    
        
        
              
        org.apache.wss4j.dom.message.WSSecSignature builderSig = new WSSecSignature();

        builderSig.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
               
        org.apache.wss4j.dom.message.WSSecHeader  secHeader = new WSSecHeader();
      
        secHeader.insertSecurityHeader(header2.getOwnerDocument());        

        Properties config = new Properties();
        config.load(new FileInputStream(“merlin.properties”)) ;
        Crypto crypto = CryptoFactory.getInstance(config);
        //dobbiamo capire perche la seguente serve, invece di prendere dal properties
        builderSig.setUserInfo(“<Nome Alias>”,”<Password>”);
        builderSig.setUseSingleCertificate(true);
        secHeader.setMustUnderstand(false);
        secHeader.getSecurityHeader().removeAttribute(“S:mustUnderstand”);

        builderSig.appendBSTElementToHeader(secHeader);    
        
        builderSig.build((Document)root, crypto, secHeader);

        printNode((Document)root);
               
      }
      catch (Exception ex) {
        ex.printStackTrace();
        System.exit(-1);
      } 
    }

    return true;
  }


  public boolean handleFault(SOAPMessageContext smc) {
    // addDigitalSignature(smc);
    return true;
  }

  // nothing to clean up
  public void close(MessageContext messageContext) {
  }

}

Di seguito il file di merlin.properties:

org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin
org.apache.wss4j.crypto.merlin.keystore.type=jks
org.apache.wss4j.crypto.merlin.keystore.password=<Password>
org.apache.wss4j.crypto.merlin.keystore.alias=<Nome Alias>
org.apache.wss4j.crypto.merlin.keystore.file=<Nome File>.jks

l xml prodotto avrà un header così composto:

<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:BinarySecurityToken
EncodingType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary”
ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3″
wsu:Id=”X509-C672A11E5F8017AFA114337688056892″>MIIDWjCCAkICCQCzH8uW6SulfzANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTESMBAGA1UECAwJS3Jvbm9iZXJnMQ4wDAYDVQQHDAVWYXhqbzERMA8GA1UECgwIR1RFQ0ggRzIxDjAMBgNVBAsMBUlUIERDMRkwFwYDVQQDDBBzdGFnZS1zcG4tZ21zLTAyMB4XDTExMTIxNTE1MDkyMVoXDTIxMTIxMjE1MDkyMVowbzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCUtyb25vYmVyZzEOMAwGA1UEBwwFVmF4am8xETAPBgNVBAoMCEdURUNIIEcyMQ4wDAYDVQQLDAVJVCBEQzEZMBcGA1UEAwwQc3RhZ2Utc3BuLWdtcy0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM5qyhAUFE4lY8rLfGqT1ZjhC4DGTCt8++eBK9xN+Li2cGbqHJBghl1U/6LgHR8/KDYDf0dWKXp89eVIYDpxRhIJgdnFnRbk2/I7Vbq67pyTSkk6DgdyyS55EhKr8Zzb8Eh9dTJsUyWLR9FVEfxHP19ghtW6swLcrH2e+Ktd0OvR0GcOEnalx1VvGLLftyT98ppnhg6YGoyA+uQkri/82COyzbkCyRtbtXB4jq4vEMgv9dTv1l6IXQpSXRncZ3t8SGOL9m6SoHjERsSrhnS4tq6ZffkgBjgfJa2oT4qWO8KeF3yqA8Bmwyzv+v2Ow5mfj6VXcLKzUA+MG4hQ7uZ8SCkCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAbnRcqaQZXxYSn8XEzqmA5L4+ESzhugaiyMWb0n0sklC3AJOufw4gCeK++3GLhqYmhHGmt0T0P3nrcRY6w8SkPsM/Zo0tKdA+W3SrEhDxOi/nhxJoosVcxmk2Qzg9zlKrBMbCic+5OBhkqpUMXTQcl4eOgfIAEtXt8rcaARMLcFx6EWjGc37tejE3nyjtjbGYgLV0RqEsTKz/+qkRx3DZZt441ewH32p+wM6GEexYlVa9lhPi53gB5uxjXzuNGQqqacfI8da+e2JGKavb44DCGraRvUKMxGrO6uGOHoZOvxYXw8J9FVrZ4pr5D3ec7WmNPfgWMkJKjMfM5F2gh8jnkA==</wsse:BinarySecurityToken>
<ds:Signature Id=”SIG-C672A11E5F8017AFA114337688058496″
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”>
<ec:InclusiveNamespaces PrefixList=”soapenv ver”
xmlns:ec=”http://www.w3.org/2001/10/xml-exc-c14n#” />
</ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#rsa-sha1″ />
<ds:Reference URI=”#id-C672A11E5F8017AFA114337688058355″>
<ds:Transforms>
<ds:Transform Algorithm=”http://www.w3.org/2001/10/xml-exc-c14n#”>
<ec:InclusiveNamespaces PrefixList=”ver”
xmlns:ec=”http://www.w3.org/2001/10/xml-exc-c14n#” />
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm=”http://www.w3.org/2000/09/xmldsig#sha1″ />
<ds:DigestValue>ZrNB9LZb2Eu9pr0rWKg1V2p5ehc=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>GVD3r4yb38OtFPb4PgnnTpOfl60VymGr18/pAsn5hrAZUUMcuCuIPLwV+0cfIoiCTSbRohvEJojW
IXAepaIf/OqfZSsBipHTe2ExFCA36uhnwUO0LC13k+DyvpUmOn2y1g0BIg/RZkwqRy+JktThIAsq
VgTa1AYyQeKY79GG2Pcla+X7iufj2Q9BBidQkK+czNsBSUW8LdSJdq3/+4QJZscODR9c+ybOG1yO
6EyLRU36Tnw3kA2ftzve+hCtxVHeQSh+LcrD1DI4L0uwrhlpwE9ai2mOrSBNLa2q1k1TmnRzAsgv
EqdCkPImL9pySVKPB/uM0sL37Cblfn0Y9JXlkQ==
</ds:SignatureValue>
<ds:KeyInfo Id=”KI-C672A11E5F8017AFA114337688057903″>
<wsse:SecurityTokenReference wsu:Id=”STR-C672A11E5F8017AFA114337688058084″>
<wsse:Reference URI=”#X509-C672A11E5F8017AFA114337688056892″
ValueType=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3″ />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id=”TS-C672A11E5F8017AFA114337688053671″>
<wsu:Created>2015-06-08T13:06:45Z</wsu:Created>
<wsu:Expires>2015-06-08T13:06:50Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>