首页 文章

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

提问于
浏览
4

我想用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目录机制”,因为它可能会在部署期间造成很多麻烦 .

我完全迷失了,我正在寻找最简单,最快捷和最新的消费Web服务的方式,需要在Java中进行摘要式身份验证?优选尽可能少的依赖性 .

2 回答

  • 3

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

    您引用的错误消息:

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

    这是非常有用和具体的,大多数情况下发生的事情就是你只是盯着 NoSuchMethodError 或类似的东西 . 随着时间的推移,您将学会将这些识别为库版本不匹配 . 在这种情况下,库作者编写了代码来识别常见的错误情况并打印出更好的错误消息(祝福他们) .

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

    • Java类加载器是分层的,分辨率是自下而上的

    • 但负责加载核心运行时库的's a blessed class loader at the root of the hierarchy that'

    • 供应商的恶作剧已经导致很多东西被包含在核心运行时库中,这真的不应该成为在其他达尔文主义选择过程中占主导地位的捷径 . 正如您刚刚发现的那样,JAXB就是其中之一 . JAXB2实际上相当不错,但它的演变独立于核心运行时,而且,我们就是这样 .

    • JDK和JRE安装有一个名为 lib\endorsed 的文件夹,您可以在其中添加需要由根加载程序加载的JAR文件,甚至绕过_1730650中的内容 .

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

    是的,这很痛苦 . 您可以调查的一个切线是故意使用's built for JAXB 2.1. So long as you'绑定在 1.6.0_03 上部署的旧版Metro,尽管失去了Metro最近的一些改进,但这可能是更好的选择 .

    更新:这是关于此主题的blog post . 它包含一些指向更多信息的链接 .

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

相关问题