【问题标题】:Consuming SOAP WS returns Error 401 unauthorized使用 SOAP WS 未授权返回错误 401
【发布时间】:2016-04-08 09:30:37
【问题描述】:

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

【问题讨论】:

  • 你解决过这个问题吗?如果是这样,您的解决方案是什么?

标签: java web-services soap spring-ws


【解决方案1】:

我通过执行以下操作设法解决了这个问题:

如下创建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());

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并通过定义带有凭据的 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;
    
    }
    

    【讨论】:

      【解决方案3】:

      使用 HttpsUrlConnectionMessageSender 进行安全 Https 连接。这是 spring-ws-support 依赖项的一部分。此外,您可以使用 HttpsUrlConnectonMessageSender 绕过各种证书问题,例如证书公用名不匹配。

      不要使用BASE64Encoder,它是sun.misc jar 的类,不太安全。使用 Java 1.8 中存在的 Java util Base64 和 Java 版本低于 Java 1.8 的 Apache 的 Base64

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

      【讨论】:

        猜你喜欢
        • 2018-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2012-04-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多