使用wsHttpBinding调用WCF Web服务器时,Metro客户端会挂起

Osc*_*car 5 wcf wsdl ntlm java-metro-framework java-ee

我用这种方式使用Metro 1.2 生成了一个带有本地wsdl的webservice客户端:

./wsimport.sh -extension -verbose -wsdllocation service.wsdl -s src -d target service.wsdl -Xendorsed
Run Code Online (Sandbox Code Playgroud)

wsdl使用SOAP 1.2wsHttpBinding.它应该连接到使用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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我在调用每个webservice方法之前设置的:

@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;
}
Run Code Online (Sandbox Code Playgroud)

如果我使用了错误的用户名/密码,我会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]
Run Code Online (Sandbox Code Playgroud)

我也试过wget 1.12(听说1.11有NTLM的问题),但它也永远不会产生响应,只是等待.

[...]
---request end---
[writing POST file customerRequest.xml ... done]
HTTP request sent, awaiting response... 
Run Code Online (Sandbox Code Playgroud)

我已经看到其他人之前已经有过这种行为,但我一直无法找到原因.任何人都可以对此有所了解吗?Linux上的JDK 1.6.

Osc*_*car 3

我发现我在生成的客户端代码中遗漏了一行启用Addressing并将其传递给getPortsuper 方法的行:

WebServiceFeature wsAddressing = new AddressingFeature(true);

ICustomerService service =
    super.getPort(new QName("http://xmlns.example.com/services/Customer",
            "WSHttpBinding_ICustomerService"), ICustomerService.class, 
            wsAddressing);
Run Code Online (Sandbox Code Playgroud)

为什么地铁没有生成这个超出了我的范围。该方法最终看起来像这样:

@WebEndpoint(name = "WSHttpBinding_ICustomerService")
public ICustomerService getWSHttpBindingICustomerService() {
    WebServiceFeature wsAddressing = new AddressingFeature(true);

    ICustomerService service =
        super.getPort(new QName("http://xmlns.example.com/services/Customer",
                "WSHttpBinding_ICustomerService"), ICustomerService.class, 
                wsAddressing);

    NtlmAuthenticator auth = new NtlmAuthenticator(username, password);  
    Authenticator.setDefault(auth);   

    return service;
}
Run Code Online (Sandbox Code Playgroud)

这又向消息添加了 SOAP 标头:

<S:Header>
  <To xmlns="http://www.w3.org/2005/08/addressing">https://services.example.com/CustomerService.svc</To>
  <Action xmlns="http://www.w3.org/2005/08/addressing">http://xmlns.example.com/services/ICustomerService/GetCustomer</Action>
  <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
    <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
  </ReplyTo>
  <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:d33c2888-abfa-474d-8729-95d2bcd17a96</MessageID>
</S:Header>
Run Code Online (Sandbox Code Playgroud)