我正在尝试使用spring-ws使用SOAP Web服务。我能够从SOAP UI成功使用此Web服务。但是我收到了一个未经授权的例外:
org.springframework.ws.client.WebServiceTransportException: Unauthorized [401]
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)
如何成功验证?
我的代码如下:
WebServiceTemplate配置:
@Bean
public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller){
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setDefaultUri("http://ultron.illovo.net:9704/AdminService");
webServiceTemplate.setMarshaller(marshaller);
webServiceTemplate.setUnmarshaller(marshaller);
Credentials credentials = new UsernamePasswordCredentials("biqa", "welcome1");
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setCredentials(credentials);
messageSender.setReadTimeout(5000);
messageSender.setConnectionTimeout(5000);
webServiceTemplate.setMessageSender(messageSender);
return webServiceTemplate;
}
客户端:
@Autowired
WebServiceTemplate webServiceTemplate;
public CallProcedureWithResultsResponse callProcedureWithResults(String procedureName){
CallProcedureWithResults request = new CallProcedureWithResults();
request.setProcedureName(procedureName);
log.info("Calling procedure " + procedureName);
CallProcedureWithResultsResponse response = (CallProcedureWithResultsResponse) webServiceTemplate.marshalSendAndReceive("http://ultron.illovo.net:9704/AdminService/AdminService", request);
return response;
}
JUnit测试
@Test
public void testWebService(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ObieeConfiguration.class);
ObieeClient client = context.getBean(ObieeClient.class);
CallProcedureWithResultsResponse response = client.callProcedureWithResults("GetOBISVersion()");
client.printResponse(response);
context.close();
}
答案 0 :(得分:2)
我设法通过执行以下操作来解决此问题:
创建HttpUrlConnectionMessageSender的子类,如下所示:
public class WebServiceMessageSenderWithAuth extends HttpUrlConnectionMessageSender {
String user;
String password;
public WebServiceMessageSenderWithAuth(String user, String password) {
this.user = user;
this.password = password;
}
@Override
protected void prepareConnection(HttpURLConnection connection) throws IOException {
BASE64Encoder enc = new BASE64Encoder();
String userpassword = user+":"+password;
String encodedAuthorization = enc.encode( userpassword.getBytes() );
connection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);
super.prepareConnection(connection);
}
}
我的客户定义如下:
public class ObieeClient extends WebServiceGatewaySupport {
private static final Logger log = LoggerFactory.getLogger(ObieeClient.class);
public CallProcedureWithResultsResponse callProcedureWithResults(String procedureName, String webServiceURL){
CallProcedureWithResults request = new CallProcedureWithResults();
request.setProcedureName(procedureName);
log.info("Calling procedure " + procedureName);
CallProcedureWithResultsResponse response = (CallProcedureWithResultsResponse) ((JAXBElement) getWebServiceTemplate().marshalSendAndReceive(webServiceURL, request)).getValue();
return response;
}
}
最后,客户端配置为通过设置邮件发件人来使用凭据:
Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); marshaller.setContextPath("za.co.adaptit.smartdeployment.webservices.wsdl");
//set up web service client
ObieeClient client = new ObieeClient();
client.setDefaultUri(host);
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
client.setMessageSender(new WebServiceMessageSenderWithAuth("user", "password"));
response = client.callProcedureWithResults("NQSModifyMetadata('" + obieeObjectsXML +"')", server.getHost());
希望这有帮助。
答案 1 :(得分:0)
我遇到了同样的问题,并通过定义带有凭据的MessageSender然后将其设置为客户端来设法解决。我没有必要创建自定义MessageSender。
@Bean
public WebServiceMessageSender messageSender(Credentials credentials) throws Exception{
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setCredentials(credentials);
return messageSender;
}
@Bean
public Credentials credentials(){
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(USERNAME, PASSWORD);
return credentials;
}
答案 2 :(得分:0)
使用HttpsUrlConnectionMessageSender进行安全的Https连接。这是spring-ws-support依赖的一部分。此外,您可以使用HttpsUrlConnectonMessageSender绕过各种证书问题,例如证书通用名称不匹配。
不要使用BASE64Encoder,它是sun.misc jar的类,它不太安全。使用java实现的java的Base64和apache的Base64,java版本少于java 1.8
public class WebServiceMessageSenderWithAuth extends HttpsUrlConnectionMessageSender {
String user;
String password;
public WebServiceMessageSenderWithAuth(String user, String password) {
this.user = user;
this.password = password;
}
@Override
protected void prepareConnection(HttpURLConnection connection) throws IOException {
String userpassword = user+":"+password;
String encodedAuthorization = Base64.encode( userpassword.getBytes() );
connection.setRequestProperty("Authorization", "Basic " + encodedAuthorization);
//set various properties by using reference of connection according to your requirement
}
}