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。
- 使用 org.apache.cxf.bus 从 IdP 或 SP 获取 WSDL 定义,
bus.getExtension(WSDLManager.class).getDefinition()
。
- 使用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);
我正在使用 CXF 3.1.5,如何应用 proxy 设置并信任或忽略 SSL发送请求时证书?
我通过以下两种方式使用CXF。
- 使用 org.apache.cxf.bus 从 IdP 或 SP 获取 WSDL 定义,
bus.getExtension(WSDLManager.class).getDefinition()
。 - 使用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);