WebServiceTransportException: неавторизовано [401] в Spring-WS - PullRequest
3 голосов
/ 22 сентября 2008

Мы пытаемся настроить наше веб-приложение для возможности подключения к веб-службам через Spring WS. Мы попытались использовать пример из документации клиентской стороны Spring-WS, но в итоге получилось исключение WebServiceTransportException. Конфигурация XML выглядит следующим образом:

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="messageSender">
        <bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
            <property name="credentials">
                <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials">
                    <constructor-arg value="john"/>
                    <constructor-arg value="secret"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

Нам удалось настроить приложение программным способом, но эту конфигурацию не удалось "перенести" в конфигурацию Spring XML, поскольку некоторые установщики не использовали формат, ожидаемый Spring. (HttpState.setCredentials (...) принимает два параметра). Конфигурация была поднята из некоторого другого клиентского кода Spring-WS в компании.

Это конфигурация, которая работает:

 public List<String> getAll() {
    List<String> carTypes = new ArrayList<String>();

    try {
        Source source = new ResourceSource(request);
        JDOMResult result = new JDOMResult();


        SaajSoapMessageFactory soapMessageFactory = new SaajSoapMessageFactory(MessageFactory.newInstance());

        WebServiceTemplate template = new WebServiceTemplate(soapMessageFactory);

        HttpClientParams clientParams = new HttpClientParams();
        clientParams.setSoTimeout(60000);
        clientParams.setConnectionManagerTimeout(60000);
        clientParams.setAuthenticationPreemptive(true);

        HttpClient client = new HttpClient(clientParams);
        client.getState().setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials("username", "password"));

        CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender(client);

        template.setMessageSender(messageSender);
        template.sendSourceAndReceiveToResult(SERVICE_URI,
                source, result);

        // Handle the XML

    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (SOAPException e) {
        throw new RuntimeException(e);
    }

    return carTypes;
}

Кто-нибудь знает, как решить мою проблему? В каждом уроке, который я вижу, указана первая конфигурация. Кажется, что когда я устанавливаю учетные данные для объекта messageSender, они просто игнорируются ...

Ответы [ 4 ]

2 голосов
/ 16 декабря 2009

Переопределите HttpClient с помощью конструктора, который принимает параметры и передает данные через Spring с помощью constructor-args

public MyHttpClient(HttpClientParams params, UsernamePasswordCredentials usernamePasswordCredentials) {
        super(params);        
        getState().setCredentials(AuthScope.ANY, usernamePasswordCredentials);
    }
1 голос
/ 29 сентября 2008

Как вы различаете эти:

<constructor-arg value="john"/>
<constructor-arg value="secret"/>

попробуйте заменить его следующим:

<property name="userName" value="john" />
<property name="password" value="secret" />

Надеюсь, это поможет.

0 голосов
/ 04 сентября 2014

Сначала мы устанавливали учетные данные в нашем проекте следующим образом:

<bean id="authenticationEnabledCommonsHttpMessageSender" parent="commonsHttpMessageSender"
    p:credentials-ref="clientCredentials" lazy-init="true" />
<bean id="clientCredentials"
    class="org.apache.commons.httpclient.UsernamePasswordCredentials"
    c:userName="${clientCredentials.userName}"
    c:password="${clientCredentials.password}"
    lazy-init="true" />

Это наша опция с включенными полномочиями. Возникла проблема, когда мы устанавливаем такие учетные данные. Если сервер, которому мы отправляем сообщение (имеет ось Axl), не имеет учетных данных для имени пользователя, мы получаем исключение «Несанкционированный». Потому что, когда мы отслеживаем vie TCPMon, мы понимаем, что строка «username: password:» была отправлена, так как вы видите, что имя пользователя и пароль не имеют значения.

После этого мы устанавливаем учетные данные следующим образом:

public Message sendRequest(OutgoingRequest message, MessageHeaders headers,
                        EndpointInfoProvider endpointInfoProvider,
                        WebServiceMessageCallback requestCallback){
    Assert.notNull(endpointInfoProvider, "Destination provider is required!");
    final Credentials credentials = endpointInfoProvider.getCredentials();
    URI destinationUri = endpointInfoProvider.getDestination();
    for (WebServiceMessageSender messageSender : webServiceTemplate.getMessageSenders()) {
        if (messageSender instanceof CommonsHttpMessageSender) {
            HttpClient httpClient = ((CommonsHttpMessageSender) messageSender).getHttpClient();
            httpClient.getState().setCredentials(
                    new AuthScope(destinationUri.getHost(),
                            destinationUri.getPort(), AuthScope.ANY_REALM,
                            AuthScope.ANY_SCHEME), credentials
            );
            httpClient.getParams().setAuthenticationPreemptive(true);
            ((CommonsHttpMessageSender) messageSender)
                    .setConnectionTimeout(endpointInfoProvider
                            .getTimeOutDuration());
        }
    }

И методы getCredentials:

@Override
public Credentials getCredentials(){
    if (credentials != null) {
        return credentials;
    }
    String username = parameterService.usernameFor(getServiceName());
    String password = parameterService.passwordFor(getServiceName());
    if (username == null && password == null) {
        return null;
    }
    credentials = new UsernamePasswordCredentials(username, password);
    return credentials;
}
0 голосов
/ 01 мая 2013

Если вы используете defaultHttpClient, как в своем примере, используйте метод afterPropertiesSet на HTTPMessageSender, и это должно решить вашу проблему, правильно применив учетные данные

...