【问题标题】:Spring Boot web service client authenticationSpring Boot Web 服务客户端身份验证
【发布时间】:2016-02-14 21:12:25
【问题描述】:

我的目标是调用需要身份验证的网络服务(当我在浏览器中打开它的 wsdl 时,浏览器会询问我登录名+密码)。

作为基础,我使用来自this 教程的示例。

现在我必须添加身份验证配置。

根据documentation 类似配置 WebServiceTemplate bean 可能会有所帮助。

但是对于 Spring Boot,项目中没有 applicationContext.xml 或任何其他配置 xml。

那么,如何使用 Spring Boot 配置 WebServiceTemplate,或者还有什么可以解决这样的任务?

【问题讨论】:

  • 你可以随时使用@ImportResource("applicationContext.xml")导入xml

标签: spring web-services spring-boot spring-ws


【解决方案1】:

在 Spring Boot 中,您可以使用 @Bean 注释配置您的 bean。您可以为不同的 bean 使用配置类。在这些类中,您需要 @Configuaration 注释。

tutorial 描述了 Spring 教程的“第二部分”。提供教程的主要内容是:(基于Spring教程)

问题

我使用的 SOAP webservice 需要基本的 http 身份验证,所以我 需要在请求中添加身份验证标头。

无需身份验证

首先,您需要在没有 像 spring.io 上的教程一样进行身份验证。接着我会 修改带有认证头的http请求。

在自定义WebServiceMessageSender中获取http请求

原始 http 连接可在 WeatherConfiguration 中访问 班级。在 weatherClient 中,您可以在其中设置消息发送者 网络服务模板。消息发送者可以访问原始 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;
}

【讨论】:

    【解决方案2】:

    另一种解决方法是添加一个拦截器并在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)
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题并通过以下方式解决了。 基本想法是使用基本用户名和密码以及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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-30
        • 2015-06-20
        • 2012-08-28
        • 2016-11-03
        • 1970-01-01
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多