使用SOAP WS会返回错误401未授权

时间:2016-04-08 09:30:38

标签: java web-services soap spring-ws

我正在尝试使用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();
    }

3 个答案:

答案 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
   } 
}