Java 使用 CXF 通过 HTTP 基本身份验证使用 Web 服务时出现 401 错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3037221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
401 error when consuming a Web service with HTTP Basic authentication using CXF
提问by seanhodges
I'm trying to consume a remote Web service that uses HTTP basic authentication, using Apache CXF, within a JUnit test.
我正在尝试在 JUnit 测试中使用使用 HTTP 基本身份验证的远程 Web 服务,使用 Apache CXF。
The error I am getting is:
我得到的错误是:
javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://localhost:8080/services/MyService?wsdl. It failed with:
Server returned HTTP response code: 401 for URL: http://localhost:8080/services/MyService?wsdl.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:151)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:133)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:254)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:217)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
at javax.xml.ws.Service.<init>(Service.java:76)
at com.wave2.marketplace.importer.impl.adportal.ws.MyServiceService.<init>(MyServiceService.java:37)
at com.wave2.marketplace.importer.impl.adportal.MyWSTest.testConsumingTheWS(MyWSTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: http://localhost:8080/services/MyService?wsdl
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1269)
at java.net.URL.openStream(URL.java:1029)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:793)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:251)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:118)
... 26 more
Having read this StackOverflow post, I have attempted to add the auth credentials to my request context, as follows:
阅读了这篇 StackOverflow 帖子后,我尝试将身份验证凭据添加到我的请求上下文中,如下所示:
@Test
public void testConsumingTheWS() throws Exception {
URL wsdl = new URL("http://localhost:8080/services/MyService?wsdl");
MyServiceService provider = new MyServiceService(wsdl); // <-- Error occurs here
MyService service = provider.getMyService();
BindingProvider binding = (BindingProvider)service;
binding.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "username");
binding.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
Ping out = service.getPing();
assertNotNull(out);
}
However, as my in-line comment indicates, the error is occurring before the BindingProvider code is reached, so the error remains the same.
但是,正如我的内嵌注释所示,错误发生在到达 BindingProvider 代码之前,因此错误保持不变。
I did have a read of this articleand its follow-up, but so far I've had trouble determining how to go about adding the interceptor code without the use of Spring (this is for a JUnit test).
我确实阅读了这篇文章及其后续文章,但到目前为止,我无法确定如何在不使用 Spring 的情况下添加拦截器代码(这是针对 JUnit 测试的)。
How might I go about authenticating against this Web service?
我该如何针对此 Web 服务进行身份验证?
采纳答案by Pascal Thivent
According to HTTP basic authentication with JAX-WS (Client):
根据JAX-WS (Client) 的 HTTP 基本身份验证:
2. The service class creation
A constructor of the service object requires access to the WSDL. And again it does not support basic authentication out of the box. You have an option to download the wsdl file and use it locally. Another option is to use the default authenticator:
Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( USER_NAME, PASSWORD.toCharArray()); } });
2.服务类的创建
服务对象的构造函数需要访问 WSDL。同样,它不支持开箱即用的基本身份验证。您可以选择下载 wsdl 文件并在本地使用它。另一种选择是使用默认身份验证器:
Authenticator.setDefault(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( USER_NAME, PASSWORD.toCharArray()); } });
回答by Daniel Kulp
Just a point of note, you aren't using CXF. You are using the JAX-WS reference implementation built into the JDK.
请注意,您没有使用 CXF。您正在使用 JDK 中内置的 JAX-WS 参考实现。
With CXF, you CAN use Spring config for everything and not set the default Authenticator. See the page at:
使用 CXF,您可以对所有内容使用 Spring 配置,而无需设置默认身份验证器。见页面:
http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html
http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html
about the http-conf:authorization settings.
关于 http-conf:authorization 设置。