我一直在尝试获得一个与 Camel 一起工作的双向 ssl/https 代理。我已经能够使用 2-way ssl 设置 Jetty 组件,现在正尝试让它与 Http4 组件一起工作以完成代理的客户端。
当我将 jetty 流量路由到日志组件时,一切都很好,而且 2 路 ssl 信任链也很好。当我放入 Http4 组件时,它会因对等未验证异常而爆炸。我正在使用 Camel 2.7.0
这是我目前的情况
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
JettyHttpComponent jetty = context.getComponent("jetty", JettyHttpComponent.class);
SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
sslConnector.setPort(9443);
sslConnector.setKeystore("/home/brian/jboss.keystore");
sslConnector.setKeyPassword("changeit");
sslConnector.setTruststore("/home/brian/jboss.truststore");
sslConnector.setTrustPassword("changeit");
sslConnector.setPassword("changeit");
sslConnector.setNeedClientAuth(true);
Map<Integer, SslSelectChannelConnector> connectors = new HashMap<Integer, SslSelectChannelConnector>();
connectors.put(9443, sslConnector);
jetty.setSslSocketConnectors(connectors);
final Endpoint jettyEndpoint = jetty.createEndpoint("jetty:https://localhost:9443/service");
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(new File("/home/brian/User2.p12")), "Password1234!".toCharArray());
X509KeyManager keyManager = new CTSKeyManager(keystore, "user2", "Password1234!".toCharArray());
KeyManager[] keyManagers = new KeyManager[] { keyManager };
X509TrustManager trustManager = new EasyTrustManager();
TrustManager[] trustManagers = new TrustManager[] { trustManager };
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyManagers, trustManagers, null);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, new SSLSocketFactory(sslcontext,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)));
HttpComponent http4 = context.getComponent("http4", HttpComponent.class);
http4.setClientConnectionManager(new ThreadSafeClientConnManager(registry));
final Endpoint https4Endpoint = http4
.createEndpoint("https4://soafa-lite-staging:443/axis2/services/SigActService?bridgeEndpoint=true&throwExceptionOnFailure=false");
context.addRoutes(new RouteBuilder() {
@Override
public void configure() {
from(jettyEndpoint).to(https4Endpoint);
}
});
context.start();
context.stop();
}
private static class EasyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
private static class CTSKeyManager extends X509ExtendedKeyManager {
private final KeyStore keystore;
private final char[] privateKeyPassword;
private final String privateKeyAlias;
public CTSKeyManager(KeyStore keystore, String privateKeyAlias, char[] privateKeyPassword) {
this.keystore = keystore;
this.privateKeyAlias = privateKeyAlias;
this.privateKeyPassword = privateKeyPassword;
}
@Override
public String[] getServerAliases(String keyType, Principal[] issuers) {
String[] serverAliases = null;
try {
List<String> aliasList = new ArrayList<String>();
int count = 0;
Enumeration<String> aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
aliasList.add(alias);
count++;
}
serverAliases = aliasList.toArray(new String[count]);
} catch (Exception e) {
}
return serverAliases;
}
@Override
public PrivateKey getPrivateKey(String alias) {
PrivateKey privateKey = null;
try {
privateKey = (PrivateKey) keystore.getKey(alias, privateKeyPassword);
} catch (Exception e) {
}
return privateKey;
}
@Override
public String[] getClientAliases(String keyType, Principal[] issuers) {
return privateKeyAlias == null ? null : new String[] { privateKeyAlias };
}
@Override
public X509Certificate[] getCertificateChain(String alias) {
X509Certificate[] x509 = null;
try {
Certificate[] certs = keystore.getCertificateChain(alias);
if (certs == null || certs.length == 0) {
return null;
}
x509 = new X509Certificate[certs.length];
for (int i = 0; i < certs.length; i++) {
x509[i] = (X509Certificate) certs[i];
}
} catch (Exception e) {
}
return x509;
}
@Override
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
return privateKeyAlias;
}
@Override
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
return privateKeyAlias;
}
@Override
public String chooseEngineClientAlias(String[] keyType, Principal[] issuers, SSLEngine engine) {
return privateKeyAlias;
}
@Override
public String chooseEngineServerAlias(String keyType, Principal[] issuers, SSLEngine engine) {
return privateKeyAlias;
}
}
}
据我所知,代理连接两侧使用的所有 keystore /信任库之间的信任应该没问题。
这是我的堆栈轨迹
[ qtp25584663-14] HttpProducer DEBUG Executing http POST method: https4://soafa-lite-staging:443/axis2/services/SigActService?bridgeEndpoint=true&throwExceptionOnFailure=false
[ qtp25584663-14] DefaultErrorHandler DEBUG Failed delivery for exchangeId: ID-ubuntu-46528-1303140195358-0-1. On delivery attempt: 0 caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
[ qtp25584663-14] DefaultErrorHandler ERROR Failed delivery for exchangeId: ID-ubuntu-46528-1303140195358-0-1. Exhausted after delivery attempt: 1 caught: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:561)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at org.apache.camel.component.http4.HttpProducer.executeMethod(HttpProducer.java:187)
at org.apache.camel.component.http4.HttpProducer.process(HttpProducer.java:101)
at org.apache.camel.impl.converter.AsyncProcessorTypeConverter$ProcessorToAsyncProcessorBridge.process(AsyncProcessorTypeConverter.java:50)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:104)
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:272)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:98)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:89)
at org.apache.camel.processor.interceptor.TraceInterceptor.process(TraceInterceptor.java:99)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.processErrorHandler(RedeliveryErrorHandler.java:299)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:208)
at org.apache.camel.processor.DefaultChannel.process(DefaultChannel.java:269)
at org.apache.camel.processor.UnitOfWorkProcessor.process(UnitOfWorkProcessor.java:109)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:77)
at org.apache.camel.processor.DelegateAsyncProcessor.processNext(DelegateAsyncProcessor.java:98)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:89)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:68)
at org.apache.camel.component.jetty.CamelContinuationServlet.service(CamelContinuationServlet.java:109)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:534)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1351)
at org.eclipse.jetty.servlets.MultiPartFilter.doFilter(MultiPartFilter.java:97)
at org.apache.camel.component.jetty.CamelMultipartFilter.doFilter(CamelMultipartFilter.java:41)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1322)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:473)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:929)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:403)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:864)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:114)
at org.eclipse.jetty.server.Server.handle(Server.java:352)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:596)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:1068)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:805)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:218)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:426)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:508)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.access$000(SelectChannelEndPoint.java:34)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:451)
at java.lang.Thread.run(Thread.java:662)
最佳答案
好的,现在开始工作,事实证明,我对 Camel 中的端点和协议(protocol)存在根本性的误解。我应该一直在使用 https4 协议(protocol)注册一个方案并在其上设置我的 SSLSocketFactory/SSLContext。由于它使用 https 注册了一个方案,因此 Http4 组件从未使用过它。
这是我的工作解决方案,但有 2 个注意事项。
为什么我不能将 SchemeRegistry 传递给 ThreadSafeClientConnManager 而它在构造 HttpClient 时不被使用?我必须改用 HttpClientConfigurer
Jetty 存在一个问题,即 Keystore 和 Truststore 必须通过 SslSelectChannelConnector 上的路径设置,而不是通过 SSLContext(错误至少存在于 jetty 7.2.2 和 7.4.0 -> 最新)
代码:
public class CamelProxy {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
CamelContext context = new DefaultCamelContext();
final Endpoint jettyEndpoint = configureJetty(context);
final Endpoint https4Endpoint = configureHttpClient(context);
context.addRoutes(new RouteBuilder() {
@Override
public void configure() {
from(jettyEndpoint).to("log:com.smithforge.request?showAll=true").to(https4Endpoint);
}
});
context.start();
context.stop();
}
private static Endpoint configureHttpClient(CamelContext context) throws Exception {
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(new File("/home/brian/User2.p12")), "Password1234!".toCharArray());
KeyStore truststore = KeyStore.getInstance("JKS");
truststore.load(new FileInputStream(new File("/home/brian/jboss.truststore")), "changeit".toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("SunX509");
keyFactory.init(keystore, "Password1234!".toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance("SunX509");
trustFactory.init(truststore);
SSLContext sslcontext = SSLContext.getInstance("TLSv1");
sslcontext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), null);
SSLSocketFactory factory = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
final Scheme scheme = new Scheme("https4", 443, factory);
registry.register(scheme);
HttpComponent http4 = context.getComponent("http4", HttpComponent.class);
http4.setHttpClientConfigurer(new HttpClientConfigurer() {
@Override
public void configureHttpClient(HttpClient client) {
client.getConnectionManager().getSchemeRegistry().register(scheme);
}
});
http4.setClientConnectionManager(new ThreadSafeClientConnManager());
return http4
.createEndpoint("https4://soafa-lite-staging:443/axis2/services/SigActService?bridgeEndpoint=true&throwExceptionOnFailure=false");
}
private static Endpoint configureJetty(CamelContext context) throws Exception {
JettyHttpComponent jetty = context.getComponent("jetty", JettyHttpComponent.class);
SslSelectChannelConnector sslConnector = new SslSelectChannelConnector();
sslConnector.setPort(4443);
sslConnector.setKeystore("/home/brian/jboss.keystore");
sslConnector.setKeyPassword("changeit");
sslConnector.setTruststore("/home/brian/jboss.truststore");
sslConnector.setTrustPassword("changeit");
sslConnector.setPassword("changeit");
sslConnector.setNeedClientAuth(true);
sslConnector.setAllowRenegotiate(true);
Map<Integer, SslSelectChannelConnector> connectors = new HashMap<Integer, SslSelectChannelConnector>();
connectors.put(4443, sslConnector);
jetty.setSslSocketConnectors(connectors);
return jetty.createEndpoint("jetty:https://localhost:4443/service");
}
// .to("log:com.smithforge.response?showHeaders=true");
}
关于java - Apache Camel Http 和 SSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5706166/
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
Java的Collections.unmodifiableList和Collections.unmodifiableMap在Ruby标准API中是否有等价物? 最佳答案 使用freeze应用程序接口(interface):Preventsfurthermodificationstoobj.ARuntimeErrorwillberaisedifmodificationisattempted.Thereisnowaytounfreezeafrozenobject.SeealsoObject#frozen?.Thismethodretur
在Java中,可以像这样从一个字符串创建一个IO流:Readerr=newStringReader("mytext");我希望能够在Ruby中做同样的事情,这样我就可以获取一个字符串并将其视为一个IO流。 最佳答案 r=StringIO.new("mytext")和here'sthedocumentation. 关于java-Java的StringReader的Ruby等价物是什么?,我们在StackOverflow上找到一个类似的问题: https://st