Spring Boot web service client authentication

这一生的挚爱 提交于 2021-01-27 05:22:46

问题


My goal is to call web service, which is require authentification (when I opne it's wsdl in my browser, browser asks me login+password).

As a base, I use the sample from this tutorial.

And now I have to add authentification configurations.

Accoding to the documentation something like configuring WebServiceTemplate bean may help.

But with Spring Boot there are no applicationContext.xml or any other configuration xml's in a project.

So, how to configure WebServiceTemplate using Spring Boot, or what else can solve such task?


回答1:


In Spring Boot you are able to configure your beans with the @Bean annotation. You can use configuration classes for different beans. In those classes you need the @Configuaration annotation.

This tutorial describes the "second part" of the Spring tutorial. The main things of provided tutorial is: (based on the Spring tutorial)

The problem

The SOAP webservice I consume requires basic http authentication, so I need to add authentication header to the request.

Without authentication

First of all you need to have implemented a request without the authentication like in the tutorial on the spring.io. Then I will modify the http request with the authentication header.

Get the http request in custom WebServiceMessageSender

The raw http connection is accessible in the WeatherConfiguration class. There in the weatherClient you can set the message sender in the WebServiceTemplate. The message sender has access to the raw http connection. So now it’s time to extend the HttpUrlConnectionMessageSender and write custom implementation of it that will add the authentication header to the request. My custom sender is as follows:

public class WebServiceMessageSenderWithAuth extends HttpUrlConnectionMessageSender{

@Override
protected void prepareConnection(HttpURLConnection connection)
        throws IOException {

    BASE64Encoder enc = new sun.misc.BASE64Encoder();
    String userpassword = "yourLogin:yourPassword";
    String encodedAuthorization = enc.encode( userpassword.getBytes() );
    connection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);

    super.prepareConnection(connection);
}

@Bean
public WeatherClient weatherClient(Jaxb2Marshaller marshaller){

WebServiceTemplate template = client.getWebServiceTemplate();
template.setMessageSender(new WebServiceMessageSenderWithAuth());

return client;
}



回答2:


Another walk-around is to add an interceptor and add the requestHeader within the handleRequest() method from which the HttpUrlConnection can be easily derived from the TransportContextHolder;

here is the code of the interceptor class:

public class SecurityInterceptor implements ClientInterceptor {

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {

        TransportContext context = TransportContextHolder.getTransportContext();
        HttpUrlConnection connection = (HttpUrlConnection) context.getConnection();

        try {
            connection.addRequestHeader("Authorization","Basic VVNFUk5BTUU6cGFzc3dvcmQ=");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return true;
    }

    //TODO:: other methods and constructor..
}

and of course add the interceptor to the WebTemplate:

WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor()};
webServiceTemplate.setInterceptors(interceptors);
webServiceTemplate.marshalSendAndReceive(uriWebService, request)



回答3:


I faced the same issue and solved by following. Basic idea was to create CredentialsProvider with basic username and password along with AuthScope.ANY:

@Bean
public WebServiceMessageSender showReqMessageSender(@Value("${ws.username}") String username,
        @Value("${ws.passowrd}") String password) throws Exception {

    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

    return new HttpComponentsMessageSender(
        HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider)
            .addInterceptorFirst(new RemoveSoapHeadersInterceptor()).build());
}

Just for further info, this message sender bean is further used (set using class extedning WebServiceGatewaySupport)

void org.springframework.ws.client.core.support.WebServiceGatewaySupport.setMessageSender(WebServiceMessageSender messageSender)


来源:https://stackoverflow.com/questions/35398045/spring-boot-web-service-client-authentication

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!