Ale*_*dar 10 java authentication web-services jax-ws webservice-client
我正在尝试使用标准JAVA 7 JAX WS工具来使用安全(HTTPS模式)Web服务.此Web服务需要身份验证.
我已经成功将证书添加到我的本地java密钥库.我借助wsimport工具从WSDL文件生成所有需要的类.
现在我尝试使用以下调用来运行一个简单的测试:
public class ReportingWebServiceTest {
static ReportingServiceService service;
static ReportingService port;
@BeforeClass
public static void setUpBeforeClass(){
service = new ReportingServiceService();
port = service.getReportingServicePort();
Map<String, Object> rContext = ((BindingProvider) port).getRequestContext();
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Authorization", Collections.singletonList("Basic YWRtaW5AYWRhcHRsb2dpYy5jb206MTIxMjE****="));
// headers.put("Username", Collections.singletonList("*****@******.com"));
// headers.put("Password", Collections.singletonList("********"));
rContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
// rContext.put(BindingProvider.USERNAME_PROPERTY, "*****@******.com");
// rContext.put(BindingProvider.PASSWORD_PROPERTY, "********");
}
@Test
public void test() {
WEBCAMPAIGNROW row = port.getCampaignRowById(14081);
toConsole(row.toString());
}
protected static void toConsole(String msg) {
System.out.println(msg);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,它给出了以下异常:
javax.xml.ws.WebServiceException: Failed to access the WSDL at: https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl. It failed with:
Got Server returned HTTP response code: 401 for URL: https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl while opening stream from https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl.
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.tryWithMex(RuntimeWSDLParser.java:173)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:155)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:120)
at com.sun.xml.internal.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:257)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:220)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:168)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:96)
at javax.xml.ws.Service.<init>(Service.java:77)
at com.enreach.admp.reporting.ReportingServiceService.<init>(ReportingServiceService.java:42)
at me.enreach.automation.mtv3.ReportingWebServiceTest.setUpBeforeClass(ReportingWebServiceTest.java:26)
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:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
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: Got Server returned HTTP response code: 401 for URL: https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl while opening stream from https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:842)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.resolveWSDL(RuntimeWSDLParser.java:283)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.parse(RuntimeWSDLParser.java:140)
... 23 more
Caused by: java.io.IOException: Server returned HTTP response code: 401 for URL: https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at java.net.URL.openStream(URL.java:1037)
at com.sun.xml.internal.ws.wsdl.parser.RuntimeWSDLParser.createReader(RuntimeWSDLParser.java:827)
... 25 more
Run Code Online (Sandbox Code Playgroud)
如你所见,我试图应用三种不同的身份验证技术,但没有任何运气.在所有三种情况下,例外情况都是相同的.我究竟做错了什么?
PS如果我尝试在浏览器中访问WSDL,我在代码中使用的凭据确实可以正常工作.
Loc*_*Loc 26
您的问题与SSL证书无关.您的问题与身份验证有关.服务实例需要能够访问WSDL内容(在您的存根调用实际Web方法之前)但它失败了,这就是您遇到该错误的原因.
你有2个解决方案:
注册默认身份验证器:
static {
java.net.Authenticator.setDefault(new java.net.Authenticator() {
@Override
protected java.net.PasswordAuthentication getPasswordAuthentication() {
return new java.net.PasswordAuthentication("myuser", "mypasswd".toCharArray());
}
});
}
Run Code Online (Sandbox Code Playgroud)下载WSDL文档并将其保存到LOCAL存储,然后使用本地WSDL文件. 对于此解决方案,您必须创建Service实例,而不是像您一样使用生成的代码.
Service service = Service.create(
new URL(**"file:///C:/reportingService.wsdl"**),
new QName("http://services.app/", "ReportingService")
);
// ...
binding.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myuser");
binding.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypasswd");
Run Code Online (Sandbox Code Playgroud)让我们尝试一些事情:
1.)您知道服务器期望的身份验证类型吗?
2.)当您尝试访问https://reporting-stage.admp.mtv3.adtlgc.com/admp/ReportingService?wsdl时,您看到了什么吗?例如,我假设有一个IP白名单或其他东西,你会在那里输入凭证或类似的?因为我看不到任何东西.
3.)当涉及到代码时,我通过HTTP以这种方式对安全的Web服务进行身份验证:
ReportingServiceService service new ReportingServiceService();
ReportingService port = service.getReportingServicePort();
BindingProvider binding = (BindingProvider) port;
// Configure service endpoint (override defined one of the WSDL)
BindingProvider binding = (BindingProvider) port;
binding.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https..");
// Add HTTP Basic Authentification credentials to this request
binding.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "myuser");
binding.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "mypasswd");
port.getCampaignRowById(14081);
Run Code Online (Sandbox Code Playgroud)
将端点属性设置为存储在wsdl的wsdl:port ...中的任何内容,我希望看起来像这样(并且应该是默认值...):
<wsdl:service name="ReportingServiceFoo">
<wsdl:port binding="tns:ReportingServiceFoo" name="ReportingService">
<soap:address location"https://myserver.com/ReportingService">
</wsdl:port>
</wsdl:service>
Run Code Online (Sandbox Code Playgroud)
编辑:
该
BindingProvider.ENDPOINT_ADDRESS_PROPERTY
Run Code Online (Sandbox Code Playgroud)
用于在运行时设置目标端点.因此,如果Web服务的端点与wsdl中的端点不同,请确保以这种方式将其设置为实际端点.
| 归档时间: |
|
| 查看次数: |
26724 次 |
| 最近记录: |