【问题标题】:Apache Camel CXF: add TlsClientParameters programmaticallyApache Camel CXF:以编程方式添加 TlsClientParameters
【发布时间】:2018-02-15 22:13:11
【问题描述】:

我使用 Apache Camel CXF 作为生产者来调用 SOAP Web 服务。我不使用 Spring 配置,而是以编程方式完成所有操作(我是初学者,不想同时学习 Spring 和 Apache Camel)。 Web 服务使用带有自签名证书的 SSL。我将它添加到信任库,并希望能够将其添加到 CxfEndpoint,类似于我使用 https4 的方式:

KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("src/main/resources/truststore.jks");
ksp.setPassword("...");

KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("...");

SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);

CamelContext context = new DefaultCamelContext();
context.addRoutes(routeBuilder);

HttpComponent httpComponent = context.getComponent("https4", HttpComponent.class);
httpComponent.setSslContextParameters(scp);

– 但这似乎不适用于 CxfComponent。我找到了很多关于使用 Spring 添加 TlsClientParameters 和配置 CxfEndpoint 的文档,例如:apache camel cxf https not working 在这里Calling secure webservice using CXF and Camel。但是,我没有找到任何关于如何像使用 https4 甚至在路由定义中那样简单地将信任库添加到组件的提示,即:

from(ENDPOINT_URI)
.setProperty(SecurityConstants.PASSWORD, constant(PASSWORD))
.setProperty(SecurityConstants.USERNAME, constant(USERNAME))
.to("cxf://" + SERVICE_URL + "?" +
     "wsdlURL=" + WSDL_URL + "&" +
      "serviceName=" + SERVICE_NAME + "&" +
      "portName=" + PORT_NAME + "&" +
      "dataFormat=CXF_MESSAGE&" +
      "synchronous=true&" +
      "defaultOperationName=" + DEFAULT_OPERATION_NAME)
.streamCaching();

我认为这一定是一个非常简单的问题,所以我仍然希望有一些简单的方法来简单地添加信任库(甚至接受任何证书,因为它与我们的用例并不真正相关)。如果有一种简单的程序化方式,我会非常高兴。有人知道吗?

【问题讨论】:

    标签: apache ssl apache-camel cxf


    【解决方案1】:

    我通过将证书添加到 jre/lib/cacerts 中的 JVM 信任库来解决了这个问题。这是可行的,因为我可以访问将运行应用程序的机器上的 JVM。这似乎是最简单的解决方案。

    更新

    如果有人对更合适的解决方案感兴趣:CxfEndpoint 提供了一种影响 HTTPConduit 及其 TLS 参数的方法。这是修改后的代码:

    • 在 cxf 端点参数中添加“cxfEndpointConfigurer=SageEndpointConfigurer”
    • 创建端点时“SageEndpointConfigurer”将使用 TypeConverters 进行解析
    • 将 TypeConverter 添加到上下文的 TypeConverter Registry 中,即直接在 RouteBuilder 中 getContext().getTypeConverterRegistry().addTypeConverter(CxfEndpointConfigurer.class, String.class, new SageEndpointConfigurerConverter());
    • 配置 TLSParameters 并简单地从 TypeConverter 返回 CxfEndpointConfigurer

      private class SageEndpointConfigurerConverter extends TypeConverterSupport {
      
      @Override
      public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException {
          CxfEndpointConfigurer configurer = new CxfEndpointConfigurer() {
              @Override
              public void configure(AbstractWSDLBasedEndpointFactory factoryBean) {
                  // do nothing
              }
      
              @Override
              public void configureClient(Client client) {
                  URLConnectionHTTPConduit conduit = (URLConnectionHTTPConduit) client.getConduit();
                  TLSClientParameters tlsParams = new TLSClientParameters();
                  tlsParams.setDisableCNCheck(true);
                  tlsParams.setTrustManagers(new TrustManager[]{new TrustAllTrustManager()});
                  conduit.setTlsClientParameters(tlsParams);
              }
      
              @Override
              public void configureServer(Server server) {
                  //do nothing
              }
          };
          return (T) configurer;
      }
      }
      
    • TrustAllManager 就是这样实现的

      public class TrustAllTrustManager implements X509TrustManager {
      
      private static Logger LOG = LoggerFactory.getLogger(TrustAllTrustManager.class);
      
      @Override
      public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
      //do nothing, trust all certificates
      logMessage(x509Certificates, authType);
      }
      
      @Override
      public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
      //do nothing, trust all certificates
      logMessage(x509Certificates, authType);
      }
      
      @Override
      public X509Certificate[] getAcceptedIssuers() {
      return new X509Certificate[0];
      }
      
      private void logMessage(X509Certificate[] x509Certificates, String authType) {
      StringBuilder message = new StringBuilder();
      String lineSeparator = System.getProperty("line.separator");
      message.append("Trusted following certificates for authentication type '").append(authType).append("'").append(lineSeparator);
      for (X509Certificate certificate : x509Certificates) {
          message.append(certificate).append(lineSeparator);
      }
      LOG.trace(message.toString());
      }
      }
      

    【讨论】:

      猜你喜欢
      • 2014-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-29
      相关资源
      最近更新 更多