Search code examples
javaandroidsoapksoap2

Adding SAML token to Header with ksoap2 in Android


I am developing an Android App with SOAP WS, it´s working fine when I get properties from request, but when I add SAML token to Header, server returns same error every time.

Error Reading XMLStreamReader

WS Request when I send Header Element:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wss="...URL....">
   <soapenv:Header>
      <wsse:Security .....>
         <saml:Assertion ID=""........></Assertion>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <wss:consultaUnitats>
         <!--Optional:-->
         <identificadorMissatge></identificadorMissatge>
         <data></data>
      </wss:consultaUnitats>
   </soapenv:Body>
</soapenv:Envelope>

And my Java code:

private boolean doUnits(String tokenID, String data) throws IOException {
    request = new SoapObject(NAMESPACE, METHOD_NAME);       request.addProperty("identificadorMissatge", ""); //Optional
    request.addProperty("data", data);      

    envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

    envelope.headerOut = new Element[1];
    envelope.headerOut[0] = getHeader();

    envelope.setAddAdornments(false);
    envelope.implicitTypes = true;
    envelope.setOutputSoapObject(request);

    androidHttpsTransport = new HttpTransportSE(URL);
    androidHttpsTransport.debug = true;
    try {           
        androidHttpsTransport.call(SOAP_ACTION, envelope);

        Log.i("ENVELOPE", androidHttpsTransport.requestDump);
        Log.i("ENVELOPE", androidHttpsTransport.responseDump);

        if (envelope.bodyIn instanceof SoapFault) {
            String str = ((SoapFault) envelope.bodyIn).faultstring;
        Log.i("", str);
        } else {
            response = (SoapObject) envelope.bodyIn;
        Log.d("WS", String.valueOf(response));
        }
return result;
}

    private Element getHeader() {
        Element header = new Element().createElement("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "wsse:Security");
        header.addChild(Node.TEXT, tokenID);
        return header;
    }

My question:

Maybe, I need to add Element and not TEXT when I create new Element? *tokenID is a String, I added SAML inside. Is this the problem?


Solution

  • Finally I fixed and work perfectly.

    I share my code for another people have same problem.

    If you put your SAML code inside String, you need to parse and re-parse to Document. How? Here my code:

    private Element getHeader() throws XmlPullParserException, IOException {
        // First Parse
            XmlPullParserFactory factory = null;
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            XmlPullParser xpp = factory.newPullParser();
            xpp.setInput((Reader)new StringReader(tokenID));
    
        // Second Parse and create a Document        
            Document doc = new Document();
            doc.parse(xpp);
    
        //Create Element and add Child        
            Element header = new Element().createElement("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
            header.addChild(Node.ELEMENT, doc.getChild(0));
            return header;
        }
    

    Adding Header to Envelope.headerOut:

    envelope.headerOut = new Element[1];
    envelope.headerOut[0] = getHeader();
    

    I hope this code can help another developers.