问题
我使用的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;
}
我遇到了同样的问题,并通过以下方法解决。
基本思路是创建一个带有基本用户名和密码以及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进一步用于(通过扩展WebServiceGatewaySupport类进行设置)
void org.springframework.ws.client.core.support.WebServiceGatewaySupport.setMessageSender(WebServiceMessageSender messageSender)
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)
@ImportResource("applicationContext.xml")
导入 XML。 - varren