为什么安全 Spring WS 集成 return 未经授权 [401]?
Why did secure Spring WS integration return Unauthorized [401]?
我正在尝试在 Spring 引导中使用安全的第三方 SOAP Web 服务,我正在关注 Spring WS 以及描述安全集成的在线资源 Spring WS - HTTPS Client-Server Example .在资源文件夹下找到证书 .cer 和 .jks 文件后,并使用此代码包装我的配置:
@Configuration
public class WSGeneralConfig {
@Autowired
@Qualifier("WifiTouristConfig")
CredentailsConfig wifiTouristConfig;
@Autowired
@Qualifier("TradeinWSConfig")
CredentailsConfig tradeinWSConfig;
@Autowired
ClientInterceptor[] interceptors;
@Bean
public WifiToursitWrapper wifiToursitWrapper(@Value("${tibco.wifi.tourist.url}") String uri) throws Exception {
WifiToursitWrapper wifiToursitWrapper = new WifiToursitWrapper();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.usp.tibco.wifi");
wifiToursitWrapper.setMarshaller(marshaller);
wifiToursitWrapper.setUnmarshaller(marshaller);
wifiToursitWrapper.setDefaultUri(uri);
wifiToursitWrapper.setInterceptors(interceptors);
wifiToursitWrapper.setMessageSender(
httpComponentsMessageSender(wifiTouristConfig.getUsername(), wifiTouristConfig.getPassword()));
return wifiToursitWrapper;
}
public HttpComponentsMessageSender httpComponentsMessageSender(String userName, String password) throws Exception {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setCredentials(new UsernamePasswordCredentials(userName, password));
httpComponentsMessageSender.setHttpClient(httpClient());
httpComponentsMessageSender.setAuthScope(AuthScope.ANY);
httpComponentsMessageSender.afterPropertiesSet();
return httpComponentsMessageSender;
}
public HttpClient httpClient() throws Exception {
return HttpClientBuilder
.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE))
.addInterceptorFirst(new RemoveSoapHeadersInterceptor()).build();
}
public SSLContext sslContext() throws Exception {
File file = new ClassPathResource("cert/cacerts.jks").getFile();
return SSLContextBuilder.create().loadTrustMaterial(file, "jksPassword".toCharArray()).build();
}
}
客户class也喜欢
public class WifiToursitWrapper extends WebServiceGatewaySupport {
@SoapOperationName(systemName = SystemName.TIBCO, operationName = "RegisterByIntlNo")
public RegisterByIntlNoResponse registerByIntlNo(RegisterByIntlNoRequest request) {
return (RegisterByIntlNoResponse) getWebServiceTemplate().marshalSendAndReceive(request,
message -> ((SoapMessage) message)
.setSoapAction("/RegisterByIntlNo"));
}
}
不幸的是,我得到了未经授权的异常,我不知道那是什么根本原因?这是异常堆栈跟踪的快照
org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:609)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at com.etisalat.account.wrapper.WifiToursitWrapper.registerByIntlNo(WifiToursitWrapper.java:25)
我通过在我的请求中添加 Base Authentication 解决了这个问题,在这个问题的答案 Consuming SOAP WS returns Error 401 unauthorized 的帮助下,我为我的案例更改了一些小代码。
private HttpComponentsMessageSender httpComponentsMessageSender(String userName, String password) throws Exception {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setHttpClient(httpClient(userName, password));
return httpComponentsMessageSender;
}
private HttpClient httpClient(String username, String password) throws Exception {
List<Header> headers = new ArrayList<>();
BasicHeader authHeader = new BasicHeader("Authorization", "Basic " + base64authUserPassword(username, password));
headers.add(authHeader);
RequestDefaultHeaders reqHeader = new RequestDefaultHeaders(headers);
return HttpClientBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE))
.addInterceptorFirst(new RemoveSoapHeadersInterceptor()).addInterceptorLast(reqHeader).build();
}
private String base64authUserPassword(String username, String password) {
String userpassword = username + ":" + password;
String encodedAuthorization = new String(Base64.getEncoder().encode(userpassword.getBytes()));
return encodedAuthorization;
}
我正在尝试在 Spring 引导中使用安全的第三方 SOAP Web 服务,我正在关注 Spring WS 以及描述安全集成的在线资源 Spring WS - HTTPS Client-Server Example .在资源文件夹下找到证书 .cer 和 .jks 文件后,并使用此代码包装我的配置:
@Configuration
public class WSGeneralConfig {
@Autowired
@Qualifier("WifiTouristConfig")
CredentailsConfig wifiTouristConfig;
@Autowired
@Qualifier("TradeinWSConfig")
CredentailsConfig tradeinWSConfig;
@Autowired
ClientInterceptor[] interceptors;
@Bean
public WifiToursitWrapper wifiToursitWrapper(@Value("${tibco.wifi.tourist.url}") String uri) throws Exception {
WifiToursitWrapper wifiToursitWrapper = new WifiToursitWrapper();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.usp.tibco.wifi");
wifiToursitWrapper.setMarshaller(marshaller);
wifiToursitWrapper.setUnmarshaller(marshaller);
wifiToursitWrapper.setDefaultUri(uri);
wifiToursitWrapper.setInterceptors(interceptors);
wifiToursitWrapper.setMessageSender(
httpComponentsMessageSender(wifiTouristConfig.getUsername(), wifiTouristConfig.getPassword()));
return wifiToursitWrapper;
}
public HttpComponentsMessageSender httpComponentsMessageSender(String userName, String password) throws Exception {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setCredentials(new UsernamePasswordCredentials(userName, password));
httpComponentsMessageSender.setHttpClient(httpClient());
httpComponentsMessageSender.setAuthScope(AuthScope.ANY);
httpComponentsMessageSender.afterPropertiesSet();
return httpComponentsMessageSender;
}
public HttpClient httpClient() throws Exception {
return HttpClientBuilder
.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE))
.addInterceptorFirst(new RemoveSoapHeadersInterceptor()).build();
}
public SSLContext sslContext() throws Exception {
File file = new ClassPathResource("cert/cacerts.jks").getFile();
return SSLContextBuilder.create().loadTrustMaterial(file, "jksPassword".toCharArray()).build();
}
}
客户class也喜欢
public class WifiToursitWrapper extends WebServiceGatewaySupport {
@SoapOperationName(systemName = SystemName.TIBCO, operationName = "RegisterByIntlNo")
public RegisterByIntlNoResponse registerByIntlNo(RegisterByIntlNoRequest request) {
return (RegisterByIntlNoResponse) getWebServiceTemplate().marshalSendAndReceive(request,
message -> ((SoapMessage) message)
.setSoapAction("/RegisterByIntlNo"));
}
}
不幸的是,我得到了未经授权的异常,我不知道那是什么根本原因?这是异常堆栈跟踪的快照
org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:609)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at com.etisalat.account.wrapper.WifiToursitWrapper.registerByIntlNo(WifiToursitWrapper.java:25)
我通过在我的请求中添加 Base Authentication 解决了这个问题,在这个问题的答案 Consuming SOAP WS returns Error 401 unauthorized 的帮助下,我为我的案例更改了一些小代码。
private HttpComponentsMessageSender httpComponentsMessageSender(String userName, String password) throws Exception {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setHttpClient(httpClient(userName, password));
return httpComponentsMessageSender;
}
private HttpClient httpClient(String username, String password) throws Exception {
List<Header> headers = new ArrayList<>();
BasicHeader authHeader = new BasicHeader("Authorization", "Basic " + base64authUserPassword(username, password));
headers.add(authHeader);
RequestDefaultHeaders reqHeader = new RequestDefaultHeaders(headers);
return HttpClientBuilder.create()
.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext(), NoopHostnameVerifier.INSTANCE))
.addInterceptorFirst(new RemoveSoapHeadersInterceptor()).addInterceptorLast(reqHeader).build();
}
private String base64authUserPassword(String username, String password) {
String userpassword = username + ":" + password;
String encodedAuthorization = new String(Base64.getEncoder().encode(userpassword.getBytes()));
return encodedAuthorization;
}