Spring Boot Web服务客户端身份验证

6
我的目标是调用需要身份验证的web服务(当我在浏览器中打开其wsdl时,浏览器会要求我输入登录名和密码)。
作为基础,我使用了这个教程中的示例。
现在我必须添加身份验证配置。
根据文档,像配置WebServiceTemplate bean这样的操作可能有所帮助。
但是在Spring Boot中,项目中没有applicationContext.xml或任何其他配置xml文件。
那么,如何使用Spring Boot配置WebServiceTemplate,或者还有什么其他方法可以解决此任务?

1
你可以随时使用 @ImportResource("applicationContext.xml") 导入 XML。 - varren
3个回答

5
在Spring Boot中,您可以使用`@Bean`注解配置bean。您可以使用不同的配置类来为不同的bean进行配置。在这些类中,您需要使用`@Configuration`注解。
这个教程描述了Spring教程的“第二部分”。提供的教程的主要内容是:(基于Spring教程)

问题

我使用的SOAP webservice需要基本的http身份验证,因此我需要添加身份验证头到请求中。

没有身份验证

首先,您需要像spring.io上的教程一样实现一个没有身份验证的请求。然后,我将修改带有身份验证头的http请求。

在自定义WebServiceMessageSender中获取http请求

原始的http连接可以在WeatherConfiguration类中访问。在那里,在weatherClient中,您可以在WebServiceTemplate中设置消息发送器。消息发送器可以访问原始的http连接。所以现在是时候扩展HttpUrlConnectionMessageSender并编写其自定义实现,将身份验证头添加到请求中了。我的自定义发送器如下:

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

1

我遇到了同样的问题,并通过以下方法解决。 基本思路是创建一个带有基本用户名和密码以及AuthScope.ANYCredentialsProvider

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

仅供参考,此消息发送bean进一步用于(通过扩展WebServiceGatewaySupport类进行设置)

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

0
另一种解决方法是添加一个拦截器,并在handleRequest()方法中添加requestHeader,从中可以轻松地从TransportContextHolder获取HttpUrlConnection
以下是拦截器类的代码:
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..
}

当然也要将拦截器添加到WebTemplate中:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接