使用Java的摘要式身份验证来使用WCF服务

时间:2013-02-15 13:57:44

标签: java soap jax-ws axis2 java-metro-framework

我想用Java创建一个连接到需要摘要式身份验证的Web服务的客户端。由于我不熟悉java和java堆栈,我做了一个研究,遇到了jax-ws,axis2,xcf和metro。我已经了解到JAX-WS是一个API,JDK中有一个参考实现,但缺少摘要授权支持。

我的第一次尝试是使用axis2,因为Eclipse IDE中有对它的内置支持。以下代码似乎遵循摘要式身份验证工作流程,但最终它仍然无法通过授权。

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());

我的第二次尝试是使用metro框架,但是我得到了一些与JAXB版本相关的错误。

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

我必须使用JDK 1.6.0_03,所以我猜这是因为JDK版本不匹配,但我也不想使用建议的“endorsed目录机制”,因为它可能会在部署期间造成很多麻烦。

我完全迷失了,我正在寻找最简单,最快捷,最新的方式来使用需要在Java中进行摘要式身份验证的Web服务?最好尽可能少依赖。

2 个答案:

答案 0 :(得分:3)

Java类加载很乱,抱歉。根本原因是.NET世界中没有像.NET一样的强名称,因此运行时链接程序会获取类路径中首先出现的匹配项,无论是否是编译代码的库版本。 OSGi系统解决了这个问题,但它从未获得主流采用。

您引用的错误消息:

  

java.lang.LinkageError:正在从引导类加载器加载JAXB 2.1 API,但此RI需要2.2 API。

非常有用且具体,大部分时间发生的事情都是你盯着NoSuchMethodError或类似的东西。随着时间的推移,您将学会将这些识别为库版本不匹配。在这种情况下,库作者编写了代码来识别常见的错误情况并打印出更好的错误消息(祝福&#39; em)。

Rant over,这里有一些我希望能让你走上正轨的信息:

  • Java类加载器是分层的,分辨率是自下而上的
  • 但是在层次结构的根目录中有一个受祝福的类加载器,它负责加载核心运行时库
  • 供应商shenanigans已经导致很多东西被包含在核心运行时库中,而这些东西确实不应该存在,因为它是在其他Darwinistic选择过程中成为主导的捷径。 JAXB就是其中之一,正如您刚刚发现的那样。 JAXB2实际上相当不错,但它的演变独立于核心运行时,而且,我们就是这样。
  • JDK和JRE安装有一个名为lib\endorsed的文件夹,您可以在其中添加需要由根加载程序加载的JAR文件,甚至绕过rt.jar中的内容。

总之,如果您手动将2.2版本的JAXB库添加到%JAVA_HOME%\lib\endorsed,那么它应该覆盖包含的2.1版本,并且您的Web服务客户端将部署。这将在每个将运行Web服务客户端的系统上发生,直到JDK更新为包含JAXB 2.2的7.x版本。如果同一个JVM正在运行其他基于JAXB的应用程序,那么这些应用程序可能会或可能不会中断。

是的,这很痛苦。您可以调查的切线是故意使用为JAXB 2.1构建的旧版Metro。只要您必须在1.6.0_03上部署,这可能是更好的选择,尽管最近失去了Metro的一些改进。

更新:此处有关于此主题的blog post。它包含一些指向更多信息的链接。

答案 1 :(得分:1)

Metro框架太复杂,无法配置,我发现的文档不完整。所以我使用Apache Axis2完成了它。

要遵循的步骤:

  • 下载并解压缩Apache Axis2二进制文件。
  • 参考所有jar文件
  • 转到/ bin文件夹并使用wsdl2java生成客户端代码。
  

wsdl2java -S src -uri“wsdl_file_location”

src文件夹下的所有内容复制到您的Java应用程序,并按如下方式连接到该服务:

//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);