Using WCF Service with Digest Authentication with Java

I want to create a Java client that connects to a web service that requires a Digest check. Since I am not familiar with java and java stack, I did some research and came across jax-ws, axis2, xcf and metro. I found out that JAX-WS is an API and there is a reference implementation in the JDK, but it lacks support for digest authorization.

My first attempt was to use axis2, as the Eclipse IDE has built-in support. The following code seems to correspond to the digest authentication processing process, but somehow it still does not perform authorization at 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 the metro infrastructure, but I am getting 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 need to use JDK 1.6.0_03, so I assume this is due to a mismatch in the JDK version, but I also do not want to use the proposed "approved directories mechanism" because it can cause a lot of problems during deployment.

I'm completely lost and I'm looking for the easiest, fastest and most modern way to use a web service that requires Digest authentication in Java. Preferably with the smallest possible dependencies.

+4
source share
2 answers

The Metro structure was too complex to configure, and the documents found were incomplete. So I did it with Apache Axis2 .

Stages:

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

wsdl2java -S src -uri "wsdl_file_location"

Copy everything to the src folder in the 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); 
+1
source

Loading Java classes is a mess, sorry. The main reason is that there are no strong names like those in the .NET world, and therefore the runtime linker accepts any match, primarily in the classpath, regardless of whether there was a version of the library with which it was compiled code. The OSGi system solves this problem, but it never received the usual adoption.

The error message you specified is:

java.lang.LinkageError: JAXB 2.1 API is loaded from bootstrap bootloader, but API 2.2 is required for this RI.

uncharacteristically useful and specific, in most cases, what happens instead, you should look at NoSuchMethodError or something like that. Over time, you will learn to recognize them as inconsistencies in the library version. In this case, the author (s) of the library wrote the code to recognize the general case of an error and print the best error message (bless).

Repeat, here is some information that I hope will set you on the correct track:

  • Java class loaders are hierarchical, and resolution is from bottom to top
  • but there is a blissful class loader at the root of the hierarchy responsible for loading the main runtime library.
  • The shenanigans vendors have led many to get into the main runtime library, which really shouldn't have been there, as it is a shortcut to becoming dominant in the Darwinist selection process. JAXB is one of these things as you just found out. JAXB2 is actually pretty decent, but it develops regardless of the main runtime and, well, here we are.
  • The JDK and JRE installation has a folder called lib\endorsed , where you can add JAR files that must be loaded by the root loader, bypassing even what is in rt.jar .

In general, if you manually add the version of the JAXB library version 2.2 to %JAVA_HOME%\lib\endorsed , then it should override version 2.1 of the version and your web service client will be deployed. This should happen on every system that starts the web service client until the JDK is upgraded to version 7.x, which includes JAXB 2.2. If the same JVM runs other JAXB-based applications, they may or may not be damaged as a result.

Yes, it hurts. The tangent you can explore is the intentional use of the old version of Metro built for JAXB 2.1. As long as you are tied to the deployment on 1.6.0_03 , this may be the best option, even though some of the latest Metro improvements have been lost.

Updated: here 's a blog post on this topic. It contains some links to additional information.

+3
source

All Articles