CXF Bus 和 STSClient 如何处理 SSL Certificate 和 Proxy?

How does CXF Bus and STSClient deal with SSL Certificate and Proxy?

我正在使用 CXF 3.1.5,如何应用 proxy 设置并信任或忽略 SSL发送请求时证书

我通过以下两种方式使用CXF

  1. 使用 org.apache.cxf.bus 从 IdP 或 SP 获取 WSDL 定义,bus.getExtension(WSDLManager.class).getDefinition()
  2. 使用org.apache.cxf.ws.security.trust.STSClient请求安全令牌。stsClient.requestSecurityToken()

而且我认为我需要使用代码而不是配置文件进行配置,因为我的调用者向我发送了有关代理和 SSL 证书的信息。

非常感谢!

经过进一步研究,我发现了一些东西。 要解决第一个问题,请添加以下代码:
ResourceManager extension = bus.getExtension(ResourceManager.class); extension.addResourceResolver(new ResourceResolver() { @Override public <T> T resolve(String resourceName, Class<T> resourceType) { return null; } @Override public InputStream getAsStream(String name) { if (!name.startsWith("https")) { return null; } org.apache.http.client.HttpClient httpClient = HttpUtils.createHttpClient(setting); HttpGet httpGet = new HttpGet(name); try { HttpResponse httpResponse = httpClient.execute(httpGet); return httpResponse.getEntity().getContent(); } catch (IOException e) { e.printStackTrace(); return null; } } });
然后我可以获得 WSDL 定义,但我仍然不知道如何解决第二个问题,我正在尝试使用 HTTPConduit((HTTPConduit)stsClient.getClient().getConduit()),但是当调用 stsClient.getClient() 时, cxf 将尝试加载那些 XML 模式,这将导致以下异常:

org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service. at org.apache.cxf.wsdl11.WSDLServiceFactory.create(WSDLServiceFactory.java:170) at org.apache.cxf.ws.security.trust.AbstractSTSClient.createClient(AbstractSTSClient.java:657) at org.apache.cxf.ws.security.trust.AbstractSTSClient.getClient(AbstractSTSClient.java:480) ... Caused by: org.apache.ws.commons.schema.XmlSchemaException: Unable to locate imported document at 'https://...&xsd=ws-trust-1.3.xsd', relative to 'https://...#types1'. at org.apache.cxf.catalog.CatalogXmlSchemaURIResolver.resolveEntity(CatalogXmlSchemaURIResolver.java:76) at org.apache.ws.commons.schema.SchemaBuilder.resolveXmlSchema(SchemaBuilder.java:684) at org.apache.ws.commons.schema.SchemaBuilder.handleImport(SchemaBuilder.java:538) at org.apache.ws.commons.schema.SchemaBuilder.handleSchemaElementChild(SchemaBuilder.java:1516) at org.apache.ws.commons.schema.SchemaBuilder.handleXmlSchemaElement(SchemaBuilder.java:659) at org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaCollection.java:551) at org.apache.cxf.common.xmlschema.SchemaCollection.read(SchemaCollection.java:129) at org.apache.cxf.wsdl11.SchemaUtil.extractSchema(SchemaUtil.java:140) at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:73) at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:65) at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:60) at org.apache.cxf.wsdl11.WSDLServiceBuilder.getSchemas(WSDLServiceBuilder.java:378) at org.apache.cxf.wsdl11.WSDLServiceBuilder.buildServices(WSDLServiceBuilder.java:345) at org.apache.cxf.wsdl11.WSDLServiceBuilder.buildServices(WSDLServiceBuilder.java:209) at org.apache.cxf.wsdl11.WSDLServiceFactory.create(WSDLServiceFactory.java:162) ... 32 more

这里有一些例子:http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html

找到解决方案:
实现 HTTPConduitFactory 并将其放入总线。
bus.setExtension(new MyHTTPConduitFactory(setting), HTTPConduitFactory.class)

在工厂里class:
@Override public HTTPConduit createConduit(HTTPTransportFactory f, Bus b, EndpointInfo localInfo, EndpointReferenceType target) throws IOException { return new MyHTTPConduit(settings, f, b, localInfo, target); }

MyHTTPConduit 扩展了 URLConnectionHTTPConduit
处理 SSL 证书。

    TLSClientParameters parameters = new TLSClientParameters();

    parameters.setDisableCNCheck(settings.isTurnOffHostVerifier());

    if (settings.isIgnoreServerCertificate()) {
        parameters.setTrustManagers(new TrustManager[] { new TrustAllCertsTrustManager() });
    } else {
        TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        factory.init(settings.getTrustStore());
        parameters.setTrustManagers(factory.getTrustManagers());
    }

    this.setTlsClientParameters(parameters);

TrustAllCertsTrustManager class

private class TrustAllCertsTrustManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }

}

处理代理。

        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setProxyServer(proxy.getHostName());
        httpClientPolicy.setProxyServerPort(proxy.getPort());

        this.setClient(httpClientPolicy);