174.9. SSL 支持(HTTPS)
使用 JSSE 配置实用程序
自 Camel 2.8 起,Jetty 组件通过 Camel JSSE 配置实用程序 支持 SSL/TLS 配置。这个工具大大减少了您需要写入的组件特定代码数量,并在端点和组件级别进行配置。以下示例演示了如何将 实用程序与 Jetty 组件一起使用。
组件的编程配置
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("/users/home/server/keystore.jks");
ksp.setPassword("keystorePassword");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("keyPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
JettyComponent jettyComponent = getContext().getComponent("jetty", JettyComponent.class);
jettyComponent.setSslContextParameters(scp);
基于 Spring DSL 端点配置
...
<camel:sslContextParameters
id="sslContextParameters">
<camel:keyManagers
keyPassword="keyPassword">
<camel:keyStore
resource="/users/home/server/keystore.jks"
password="keystorePassword"/>
</camel:keyManagers>
</camel:sslContextParameters>...
...
<to uri="jetty:https://127.0.0.1/mail/?sslContextParameters=#sslContextParameters"/>
...
直接配置 Jetty
jetty 开箱即用提供 SSL 支持。要使 Jetty 以 SSL 模式运行,只需使用 https:// prefix--- 例如格式化 URI:
<from uri="jetty:https://0.0.0.0/myapp/myservice/"/>
jetty 还需要知道从中加载密钥存储的位置以及要使用的密码来加载正确的 SSL 证书。设置以下 JVM 系统属性:
until Camel 2.2
-
jetty.ssl.keystore指定 Java 密钥存储文件的位置,该文件在 密钥条目 中包含 Jetty 服务器自己的 X.509 证书。密钥条目存储 X.509 证书(有效,公钥)及其关联的私钥。 -
jetty.ssl.password存储密码,这是访问密钥存储文件(这与密钥存储命令的-storepass选项提供的密码相同)。 -
jetty.ssl.keypassword密钥密码,用于访问密钥存储中的证书密钥条目(这是提供给密钥存储命令的-keypass选项的相同密码)。
从 Camel 2.3 开始
-
org.eclipse.jetty.ssl.keystore指定 Java 密钥存储文件的位置,该文件在 密钥条目 中包含 Jetty 服务器自己的 X.509 证书。密钥条目存储 X.509 证书(有效,公钥)及其关联的私钥。 -
org.eclipse.jetty.ssl.password,存储密码需要访问密钥存储文件(这是提供给密钥存储命令的-storepass选项相同的密码)。 -
org.eclipse.jetty.ssl.keypassword是密钥密码,用于访问密钥存储中证书的密钥条目(这与密钥存储命令的-keypass选项提供的密码相同)。
有关如何在 Jetty 端点上配置 SSL 的详情,请阅读 Jetty Site 中的以下文档: http://docs.codehaus.org/display/JETTY/How+to+configure+SSL
有些 SSL 属性不会直接由 Camel 公开,但 Camel 会公开底层 SslSocketConnector,它允许您设置诸如 needClientAuth 的属性,用于需要客户端证书或 wantClientAuth 用于客户端不需要证书的 mutual 身份验证,但可以有一个。各种 Camel 版本之间存在一些差别:
最多 Camel 2.2
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="sslSocketConnectors">
<map>
<entry key="8043">
<bean class="org.mortbay.jetty.security.SslSocketConnector">
<property name="password"value="..."/>
<property name="keyPassword"value="..."/>
<property name="keystore"value="..."/>
<property name="needClientAuth"value="..."/>
<property name="truststore"value="..."/>
</bean>
</entry>
</map>
</property>
</bean>
Camel 2.3, 2.4
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="sslSocketConnectors">
<map>
<entry key="8043">
<bean class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<property name="password"value="..."/>
<property name="keyPassword"value="..."/>
<property name="keystore"value="..."/>
<property name="needClientAuth"value="..."/>
<property name="truststore"value="..."/>
</bean>
</entry>
</map>
</property>
</bean>
* 从 Camel 2.5,我们切换到使用 SslSelectChannelConnector *
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="sslSocketConnectors">
<map>
<entry key="8043">
<bean class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">
<property name="password"value="..."/>
<property name="keyPassword"value="..."/>
<property name="keystore"value="..."/>
<property name="needClientAuth"value="..."/>
<property name="truststore"value="..."/>
</bean>
</entry>
</map>
</property>
</bean>
您在上述映射中用作键的值是您将 Jetty 配置为侦听的端口。
174.9.1. 在 IBM Java 上配置带有 TLS 安全性的 camel-jetty9 复制链接链接已复制到粘贴板!
camel-jetty9 组件中的默认 TLS 安全设置与 IBM Java 虚拟机不兼容。IBM Java 中的所有密码都以 前缀 SSL Passthrough 开头,即使 TLS 协议的密码也以 SSLzFCP 开头。camel-jetty9 仅支持 RFC Cipher Suite 名称,所有 SSLBlock 密码 都不受保护,且被排除。jetty 排除所有 SSL Passthrough 密码,因此没有可用于 TLS 1.2 和连接失败的密码。因为无法更改 Jetty 的 ssl 上下文的行为,所以只有临时解决方案是覆盖 Jetty9 组件中的默认 TLS 安全配置。要达到此目的,请在 Application.java 文件中方法 "sslContextParameters ()" 的末尾添加以下代码。
FilterParameters fp = new FilterParameters();
fp.getInclude().add(".*");
// Exclude weak / insecure ciphers
fp.getExclude().add("^.*_(MD5|SHA|SHA1)$");
// Exclude ciphers that don't support forward secrecy
fp.getExclude().add("^TLS_RSA_.*$");
// The following exclusions are present to cleanup known bad cipher
// suites that may be accidentally included via include patterns.
// The default enabled cipher list in Java will not include these
// (but they are available in the supported list).
/* SSL_ ciphers are not excluded
fp.getExclude().add("^SSL_.*$"); */
fp.getExclude().add("^.NULL.$");
fp.getExclude().add("^.anon.$");
p.setCipherSuitesFilter(fp);
此代码覆盖了 Jetty 中定义的排除密码,方法是删除所有 SSLBlock 密码的 排除。
174.9.2. 配置常规 SSL 属性 复制链接链接已复制到粘贴板!
从 Camel 2.5 开始提供
现在,您可以配置通用属性,适用于所有 SSL 套接字连接器(而不是上面提到的端口号),而不是每个端口号的特定于端口号的 SSL 套接字连接器。
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="sslSocketConnectorProperties">
<map>
<entry key="password"value="..."/>
<entry key="keyPassword"value="..."/>
<entry key="keystore"value="..."/>
<entry key="needClientAuth"value="..."/>
<entry key="truststore"value="..."/>
</map>
</property>
</bean>
174.9.3. 如何获取对 X509Certificate 的引用 复制链接链接已复制到粘贴板!
jetty 将证书的引用存储在 HttpServletRequest 中,您可以按照以下方式从代码访问:
HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class);
X509Certificate cert = (X509Certificate) req.getAttribute("javax.servlet.request.X509Certificate")
174.9.4. 配置常规 HTTP 属性 复制链接链接已复制到粘贴板!
从 Camel 2.5 开始提供
现在,您可以配置通用属性,适用于所有 HTTP 套接字连接器(而不是上面包括的端口号)来明确配置每个端口号的 HTTP 套接字连接器(如上面所示)。
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="socketConnectorProperties">
<map>
<entry key="acceptors" value="4"/>
<entry key="maxIdleTime" value="300000"/>
</map>
</property>
</bean>
如果 HTTP 请求由 Apache 服务器处理,并使用 mod_proxy 转发到 jetty,则原始客户端 IP 地址位于 X-Forwarded-For 标头中,HttpServletRequest.getRemoteAddr ()将返回 Apache 代理的地址。
jetty 有一个 forward 属性,它取来自 X-Forwarded-For 的值,并将它放在 HttpServletRequest remoteAddr 属性中。此属性不直接通过端点配置提供,但可以使用 socketConnectors 属性轻松添加:
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
<property name="socketConnectors">
<map>
<entry key="8080">
<bean class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<property name="forwarded" value="true"/>
</bean>
</entry>
</map>
</property>
</bean>
当现有 Apache 服务器为某个域处理 TLS 连接时,这特别有用,并将它们代理到内部的应用服务器。