Search code examples
javasoapjax-wsapache-axisjava-metro-framework

Consuming WCF Service with Digest authentication from Java


I want to create a client in Java that connects to a web service which requires Digest authentication. Since I am not familiar with java and java stack, I've made a research and came across jax-ws, axis2, xcf, and metro. I have learned JAX-WS is an API and there is a reference implementation in the JDK but it lacks the digest authorization support.

My first attempt was to use axis2 since there is a built-in support for it in the Eclipse IDE. The following code seems to follow digest authentication workflow but somehow it still fails the authorization in the end.

Service1Stub stub = new Service1Stub();

HttpTransportProperties.Authenticator authenticator = new Authenticator();
List<String> authSchemes = new ArrayList<String>();
authSchemes.add(Authenticator.DIGEST);
authenticator.setAuthSchemes(authSchemes);
authenticator.setUsername("doman user");
authenticator.setPassword("domain password");
authenticator.setPreemptiveAuthentication(true);
Options options = stub._getServiceClient().getOptions();
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, authenticator);
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, org.apache.axis2.Constants.VALUE_FALSE);

GetData getData = new GetData();
getData.setValue(25);
GetDataResponse data = stub.getData(getData);
System.out.println(data.getGetDataResult());

My second attempt was to use metro framework but I get some errors related to JAXB versions.

java.lang.LinkageError: JAXB 2.1 API is being loaded from the bootstrap classloader, but this RI needs 2.2 API.

I have to use JDK 1.6.0_03 so I guess this is happening because of a JDK version mismatch, but I also don't want to use the suggested "endorsed directory mechanism" because it might cause lots of troubles during deployment.

I am totally lost and I am looking for the simplest, quickest and up-to-date way of consuming a web service that requires Digest authentication in Java? Preferably with as little as dependencies possible.


Solution

  • Metro framework was way too complicated to configure and documents that I have found were incomplete. So I've done it with using Apache Axis2.

    Steps to follow:

    • Download and extract Apache Axis2 binaries.
    • Reference to all jar files
    • Go to /bin folder and use wsdl2java to generate client code.

    wsdl2java -S src -uri "wsdl_file_location"

    Copy everything under the src folder to your java application and connect to the service as follows:

    //Fictious is the name of the web service
    FictiousStub stub = new FictiousStub("servicelocation/fictiousService.php");
    
    HttpTransportProperties.Authenticator authenticator = new Authenticator();
    List<String> authSchemes = new ArrayList<String>();
    authSchemes.add(Authenticator.DIGEST);
    authenticator.setAuthSchemes(authSchemes);
    authenticator.setUsername("admin");
    authenticator.setPassword("12345");
    authenticator.setPreemptiveAuthentication(true);
    Options options = stub._getServiceClient().getOptions();
    options.setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, authenticator);
    options.setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, org.apache.axis2.Constants.VALUE_FALSE);