使用 wsHttpBinding 调用 WCF Web 服务器时 Metro 客户端挂起
我已经使用 Metro 1.2 生成了一个带有本地 wsdl 的 Web 服务客户端,如下所示:
./wsimport.sh -extension -verbose -wsdllocation service.wsdl -s src -d target service.wsdl -Xendorsed
wsdl 使用 SOAP 1.2
并且wsHttpBinding
。它应该连接到使用 NTLM 作为身份验证方法的 WCF 服务器。
我创建了一个Authenticator
来处理NTLM
身份验证:
public class NtlmAuthenticator extends Authenticator
{
private String username = "";
private String password = "";
public NtlmAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
}
我在调用每个Web服务方法之前设置:
@WebEndpoint(name = "WSHttpBinding_ICustomerService")
public ICustomerService getWSHttpBindingICustomerService() {
ICustomerService service =
super.getPort(new QName("http://xmlns.example.com/services/Customer",
"WSHttpBinding_ICustomerService"), ICustomerService.class);
NtlmAuthenticator auth = new NtlmAuthenticator(username, password);
Authenticator.setDefault(auth);
return service;
}
如果我使用错误的用户名/密码,我会得到一个401 Unauthorized
返回,这很好,但是当我使用正确用户名/密码时,呼叫挂起,我从未得到响应!
请求看起来像这样(用netcat捕获它,所以主机不同,并且没有https):
POST / HTTP/1.1
Content-type: application/soap+xml;charset="utf-8";action="http://xmlns.example.com/services/ICustomerService/GetCustomer"
Password: [password]
Authorization: Basic [auth]
Username: [username]
Accept: application/soap+xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.7-b01-
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:5500
Connection: keep-alive
Content-Length: 603
[xml follows]
我也尝试过wget 1.12(听说1.11有NTLM问题),但它也永远不会产生一个回应,只是等待。
[...]
---request end---
[writing POST file customerRequest.xml ... done]
HTTP request sent, awaiting response...
我已经看到 其他人之前也遇到过这种行为,但我一直无法找出原因。有人能解释一下吗? Linux 上的 JDK 1.6。
I have generated a webservice client with a local wsdl using Metro 1.2 this way:
./wsimport.sh -extension -verbose -wsdllocation service.wsdl -s src -d target service.wsdl -Xendorsed
The wsdl uses SOAP 1.2
and wsHttpBinding
. It's supposed to connect to a WCF server that's using NTLM
as authentication method.
I have created an Authenticator
to handle the NTLM
authentication:
public class NtlmAuthenticator extends Authenticator
{
private String username = "";
private String password = "";
public NtlmAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
}
Which I set before each webservice method is called:
@WebEndpoint(name = "WSHttpBinding_ICustomerService")
public ICustomerService getWSHttpBindingICustomerService() {
ICustomerService service =
super.getPort(new QName("http://xmlns.example.com/services/Customer",
"WSHttpBinding_ICustomerService"), ICustomerService.class);
NtlmAuthenticator auth = new NtlmAuthenticator(username, password);
Authenticator.setDefault(auth);
return service;
}
If I use the wrong username/password, I get a 401 Unauthorized
back, which is well and all, but when I use the correct username/password, the call hangs and I never get a response!
The request looks like this (captured it with netcat, so host is different, and no https):
POST / HTTP/1.1
Content-type: application/soap+xml;charset="utf-8";action="http://xmlns.example.com/services/ICustomerService/GetCustomer"
Password: [password]
Authorization: Basic [auth]
Username: [username]
Accept: application/soap+xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.7-b01-
Cache-Control: no-cache
Pragma: no-cache
Host: localhost:5500
Connection: keep-alive
Content-Length: 603
[xml follows]
I have also tried with wget 1.12
(heard that 1.11 had problem with NTLM), but it too never yields a response, just waits.
[...]
---request end---
[writing POST file customerRequest.xml ... done]
HTTP request sent, awaiting response...
I've seen that others have gotten this behaviour before, but I have not been able to find out why. Can anyone shed some light on this? JDK 1.6 on linux.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我发现我在生成的客户端代码中遗漏了一行启用
Addressing
并将其传递给getPort
超级方法:为什么metro没有生成这个超出了我的范围。该方法最终如下所示:
这又向消息添加了 SOAP 标头:
I found that I missed a line in my generated client code that enabled
Addressing
and pass it to thegetPort
super method:Why metro didn't generate this is beyond me. The method looked like this in the end:
This in turn added a SOAP header to the message: