Spring 启动 Web 服务客户端身份验证
Spring Boot web service client authentication
我的目标是调用网络服务,这需要身份验证(当我在浏览器中选择 wsdl 时,浏览器要求我登录名+密码)。
作为基础,我使用 this 教程中的示例。
现在我必须添加身份验证配置。
根据 documentation 配置 WebServiceTemplate bean 之类的东西可能会有所帮助。
但是使用 Spring 引导,项目中没有 applicationContext.xml 或任何其他配置 xml。
那么,如何使用Spring引导配置WebServiceTemplate,或者还有什么可以解决这样的任务?
在 Spring 引导中,您可以使用 @Bean
注释配置 bean。您可以对不同的 bean 使用配置 类。在那些 类 中,您需要 @Configuaration
注释。
此 tutorial 描述了 Spring 教程的 "second part"。提供教程的主要内容是:(基于Spring教程)
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;
}
另一种解决方法是添加一个拦截器并在 handleRequest()
方法中添加 requestHeader,从中可以轻松地从 TransportContextHolder
;[=15= 派生出 HttpUrlConnection
]
这里是拦截器的代码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..
}
当然还要将拦截器添加到 WebTemplate 中:
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor()};
webServiceTemplate.setInterceptors(interceptors);
webServiceTemplate.marshalSendAndReceive(uriWebService, request)
我遇到了同样的问题,按照以下方法解决了。
基本想法是使用基本用户名和密码以及 AuthScope.ANY
:
创建 CredentialsProvider
@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(使用 class 扩展 WebServiceGatewaySupport 设置)
void org.springframework.ws.client.core.support.WebServiceGatewaySupport.setMessageSender(WebServiceMessageSender messageSender)
我的目标是调用网络服务,这需要身份验证(当我在浏览器中选择 wsdl 时,浏览器要求我登录名+密码)。
作为基础,我使用 this 教程中的示例。
现在我必须添加身份验证配置。
根据 documentation 配置 WebServiceTemplate bean 之类的东西可能会有所帮助。
但是使用 Spring 引导,项目中没有 applicationContext.xml 或任何其他配置 xml。
那么,如何使用Spring引导配置WebServiceTemplate,或者还有什么可以解决这样的任务?
在 Spring 引导中,您可以使用 @Bean
注释配置 bean。您可以对不同的 bean 使用配置 类。在那些 类 中,您需要 @Configuaration
注释。
此 tutorial 描述了 Spring 教程的 "second part"。提供教程的主要内容是:(基于Spring教程)
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;
}
另一种解决方法是添加一个拦截器并在 handleRequest()
方法中添加 requestHeader,从中可以轻松地从 TransportContextHolder
;[=15= 派生出 HttpUrlConnection
]
这里是拦截器的代码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..
}
当然还要将拦截器添加到 WebTemplate 中:
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[]{new SecurityInterceptor()};
webServiceTemplate.setInterceptors(interceptors);
webServiceTemplate.marshalSendAndReceive(uriWebService, request)
我遇到了同样的问题,按照以下方法解决了。
基本想法是使用基本用户名和密码以及 AuthScope.ANY
:
CredentialsProvider
@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(使用 class 扩展 WebServiceGatewaySupport 设置)
void org.springframework.ws.client.core.support.WebServiceGatewaySupport.setMessageSender(WebServiceMessageSender messageSender)