Клиент Metro зависает при вызове веб-сервера WCF с помощью wsHttpBinding

Я создал клиент веб-службы с локальным wsdl, используя Metro 1.2 следующим образом:

./wsimport.sh -extension -verbose -wsdllocation service.wsdl -s src -d target service.wsdl -Xendorsed

wsdl использует SOAP 1.2 и wsHttpBinding. Предполагается подключение к серверу WCF, который использует NTLM в качестве метода аутентификации.

Я создал 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());
    }
}

Который я устанавливаю перед вызовом каждого метода веб-сервиса:

@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... 

Я видел, что другие сталкивались с таким поведением раньше, но я не удалось выяснить, почему. Может кто-нибудь пролить некоторый свет на это? JDK 1.6 на линукс.


person Oscar    schedule 15.08.2011    source источник
comment
Вы знаете, поступает ли запрос в ваше приложение WCF вообще?   -  person home    schedule 15.08.2011
comment
Я не знаю насчет тех, которые висят, я должен завтра получить логи именно для этого. У меня нет контроля над сервером WCF.   -  person Oscar    schedule 15.08.2011


Ответы (1)


Я обнаружил, что пропустил строку в сгенерированном клиентском коде, которая включала Addressing и передала ее суперметоду getPort:

WebServiceFeature wsAddressing = new AddressingFeature(true);

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

Почему метро не сгенерировало это, мне непонятно. В итоге метод выглядел так:

@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;
}

Это, в свою очередь, добавило к сообщению заголовок 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>
person Oscar    schedule 17.08.2011