SOAP webservice call with header not working

328 Views Asked by At

I'm trying to call a SOAP webservice with credentials username and password, but it's giving an error, I tried in different ways but it's the same output, it's giving this error:

//error

expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <html>@2:44 in java.io.InputStreamReader@54570a0)

No response is returned.

//variables

private static final String NAMESPACE = "http://tempuri.org/";
private static final String METHOD_NAME = "method";
private static final String SOAP_ACTION = NAMESPACE + METHOD_NAME;
private static final String URL = "https://example.com/and/service.asmx";
private static final String USER_NAME = "username";
private static final String PASSWORD = "password";
//calling web service
 SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
 PropertyInfo deviceIdPI = new PropertyInfo();
        deviceIdPI.setName("device_id");
        deviceIdPI.setValue(deviceId);
        deviceIdPI.setType(String.class);
        request.addProperty(deviceIdPI);
  SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

        // add header to envelope
        envelope.headerOut = getHeaderElement();

        System.out.println("HeaderValue " + Arrays.toString(envelope.headerOut));

        envelope.dotNet = false;
        envelope.bodyOut = request;
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        System.out.println("BodyOut " + envelope.bodyOut.toString());

        androidHttpTransport.debug = true;
        androidHttpTransport.call(SOAP_ACTION, envelope);

        SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
        System.out.println("ResponseMessage" +  response.toString());
        responseMsg = String.valueOf(response);
        System.out.println("ResponseMessage" +  response.toString());
 public static Element[] getHeaderElement() {
        // create header
        Element[] header = new Element[1];
        header[0] = new Element().createElement("http://docs.oasis-open.org/wss/2004/01/oasis- 200401-wss-wssecurity-secext-1.0.xsd","Security");
        header[0].setAttribute(null, "mustUnderstand","1");

        //username
        Element username = new Element().createElement(null, USER_NAME);
        username.addChild(Node.IGNORABLE_WHITESPACE,"CBROWN");
        header[0].addChild(Node.ELEMENT, username);

        //password
        Element pass = new Element().createElement(null,PASSWORD);
        pass.setAttribute(null, "Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
//        pass.addChild(Node.TEXT, PASSWORD);
        username.addChild(Node.ELEMENT, pass);

        return header;
    }
}
1

There are 1 best solutions below

6
jccampanero On

You can authenticate a Web Service call in two ways:

  • On one hand, you can authenticate your Web Service call at the message level, as in your code, including the necessary WS-Security related headers.
  • On the other, a Web Service call can be authenticated at the transport level, normally using the HTTP/S transport protocol and Authorization headers.

Both authentication mechanisms are in fact complementary, and the use of one of another depends on the Web Service provider.

In my opinion, the provider of your Web Service expects authentication at the transport level at least and, when you send the SOAP request without the necessary headers, it is returning a 401 HTML page, which is causing the error you are describing:

expected: START_TAG {http://schemas.xmlsoap.org/soap/envelope/}Envelope (position:START_TAG <html>@2:44 in java.io.InputStreamReader@54570a0)

According to this related SO question, you can provide the necessary headers with something like this:

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

// add header to envelope: probably you can get rid of it
// when using HTTP transport authentication
// envelope.headerOut = getHeaderElement();

System.out.println("HeaderValue " + Arrays.toString(envelope.headerOut));

envelope.dotNet = false;
envelope.bodyOut = request;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
System.out.println("BodyOut " + envelope.bodyOut.toString());

androidHttpTransport.debug = true;

// Note the inclusion of the required headers
List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
headerList.add(new HeaderProperty(
        "Authorization",
        "Basic " + org.kobjects.base64.Base64.encode((USER_NAME + ":" + PASSWORD).getBytes())
        // Or, using android.util.Base64
        // "Basic " + Base64.encodeToString((USER_NAME + ":" + PASSWORD).getBytes(), Base64.DEFAULT)
));

androidHttpTransport.call(SOAP_ACTION, envelope, headerList);

SoapPrimitive response = (SoapPrimitive)envelope.getResponse();
System.out.println("ResponseMessage" +  response.toString());
responseMsg = String.valueOf(response);
System.out.println("ResponseMessage" +  response.toString());