使用 Apache Camel 的 netty4-http 组件发出 Https 请求
Make Https request with the netty4-http component of Apache Camel
我使用 Apache Camel 公开了一个简单的 REST 服务,例如 Spring 启动微服务,它使用 netty4-http 组件创建对 https 服务的请求。
public class RoutingTest extends RouteBuilder {
@Override
public void configure() throws Exception {
restConfiguration()
.host("localhost")
.port("8080");
rest().post("test")
.route()
.setBody(constant("message=Hello"))
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethod.POST))
.setHeader(Exchange.CONTENT_TYPE, constant("application/x-www-form-urlencoded"))
.to("netty4-http:https://localhost/service/test");
}
}
当我调用 http://localhost:8080/test
时,我在路由调用 https://localhost/service/test
时收到 400 Bad Request 错误 service.From 我读到的日志显示请求以 HTTP 而不是 HTTPS 格式到达,我没有'不明白为什么:
You're speaking plain HTTP to an SSL-enabled server port. Instead use
the HTTPS scheme to access this URL, please.
如果我使用 Postman 调用服务 https://localhost/service/test
,它会正常工作。
SSL 配置了自签名证书。
如何使用 apache camel 中的 netty 组件创建正确的 https 请求?文档只建议更换协议,顶多有几个选项是行不通的。
更新(已解决,见下文)
我是这样更新调用的
.to("netty4-http:https://localhost/dpm/idp/oauth/token?ssl=true&sslContextParameters=#sslContextParameters");
ssl = true
参数是必需的,我还为 SSLContextParameters
配置了 bean,如下所示:
@Bean(name = "sslContextParameters")
public static SSLContextParameters sslParameters() throws KeyManagementException, GeneralSecurityException, IOException {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("C:/myfolder/test.jks");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("jskPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(new TrustSelfSignedStrategy());
SSLContext sslcontext = builder.build();
scp.createSSLContext().setDefault(sslcontext);
return scp;
}
我正在与已弃用的 类 作斗争。为了进行测试,我只弃用了一种方法,因为我应该使用继承。
如果我理解正确,我必须从我的自签名证书(.crt 和 .key 文件)开始为信任区生成一个 JKS
文件。完成后,我添加了 KeyStoreParameters
和密码的说明。
差不多解决了,但是现在执行
的时候出现这个错误
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
您可能需要 configure a sslContextParameters
object that you can use to configure the Netty component SSL。
我不确定参数名称。文档说 sslContextParameters
,但我认为是 sslContextParametersRef
。
.to("netty4-http:https://localhost/service/test?sslContextParametersRef=#sslConfig");
#sslConfig
表示Camel可以从注册表中获取标识符为sslConfig
的对象。因此,例如 Spring 这将是一个 Spring 托管 Bean,ID 为 sslConfig
.
Netty component (not http) also has a parameter ssl=true
. No idea if this is also needed for Netty-http。因此,您将不得不使用这些不同的参数进行一些测试。
顺便说一下,Netty 组件的文档有 an SSL example with context parameter configuration 等等。看看吧。
已解决。缺少自签名证书所需的一些说明。
下面是完整的bean。
@Bean(name = "sslContextParameters")
public static SSLContextParameters sslParameters() throws KeyManagementException, GeneralSecurityException, IOException {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("C:/myfolder/test.jks");
ksp.setPassword("jskPassword");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("jskPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLContext sslcontext = builder.build();
scp.createSSLContext().setDefault(sslcontext);
// Necessary for the the self-signed server certificate
TrustManagersParameters tmp = new TrustManagersParameters();
tmp.setKeyStore(ksp);
scp.setTrustManagers(tmp);
return scp;
}
至于 test.jks
文件,我使用 keytool
创建了它,该工具随 JDK
一起提供,用于管理证书(创建、导出和导入)。
在我已经使用 OpenSSL
创建证书的情况下,我只需要创建要导入的 JKS (Java Keystore)
文件。因为需要在 P12
文件中转换证书(它应该是一个存档),最后在 JKS
.
中
在操作过程中,您将被要求输入两个文件的密码
- openssl pkcs12 -export -in test.crt -inkey test.key -out test.p12
- keytool -importkeystore -srckeystore test.p12 -destkeystore test.jks -srcstoretype pkcs12
- keytool -importkeystore -srckeystore test.jks -destkeystore test.jks -deststoretype pkcs12
这里test是我的证书文件名。最后一个操作不是强制性的,但 keytool 本身建议将 JKS
格式(如果我理解正确的话是专有格式)迁移到更常见的 PKCS12
格式。
代码中的值jskPassword
是我在创建keystore时设置的密码
希望对你有所帮助。
我使用 Apache Camel 公开了一个简单的 REST 服务,例如 Spring 启动微服务,它使用 netty4-http 组件创建对 https 服务的请求。
public class RoutingTest extends RouteBuilder {
@Override
public void configure() throws Exception {
restConfiguration()
.host("localhost")
.port("8080");
rest().post("test")
.route()
.setBody(constant("message=Hello"))
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethod.POST))
.setHeader(Exchange.CONTENT_TYPE, constant("application/x-www-form-urlencoded"))
.to("netty4-http:https://localhost/service/test");
}
}
当我调用 http://localhost:8080/test
时,我在路由调用 https://localhost/service/test
时收到 400 Bad Request 错误 service.From 我读到的日志显示请求以 HTTP 而不是 HTTPS 格式到达,我没有'不明白为什么:
You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please.
如果我使用 Postman 调用服务 https://localhost/service/test
,它会正常工作。
SSL 配置了自签名证书。
如何使用 apache camel 中的 netty 组件创建正确的 https 请求?文档只建议更换协议,顶多有几个选项是行不通的。
更新(已解决,见下文)
我是这样更新调用的
.to("netty4-http:https://localhost/dpm/idp/oauth/token?ssl=true&sslContextParameters=#sslContextParameters");
ssl = true
参数是必需的,我还为 SSLContextParameters
配置了 bean,如下所示:
@Bean(name = "sslContextParameters")
public static SSLContextParameters sslParameters() throws KeyManagementException, GeneralSecurityException, IOException {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("C:/myfolder/test.jks");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("jskPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(new TrustSelfSignedStrategy());
SSLContext sslcontext = builder.build();
scp.createSSLContext().setDefault(sslcontext);
return scp;
}
我正在与已弃用的 类 作斗争。为了进行测试,我只弃用了一种方法,因为我应该使用继承。
如果我理解正确,我必须从我的自签名证书(.crt 和 .key 文件)开始为信任区生成一个 JKS
文件。完成后,我添加了 KeyStoreParameters
和密码的说明。
差不多解决了,但是现在执行
的时候出现这个错误PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
您可能需要 configure a sslContextParameters
object that you can use to configure the Netty component SSL。
我不确定参数名称。文档说 sslContextParameters
,但我认为是 sslContextParametersRef
。
.to("netty4-http:https://localhost/service/test?sslContextParametersRef=#sslConfig");
#sslConfig
表示Camel可以从注册表中获取标识符为sslConfig
的对象。因此,例如 Spring 这将是一个 Spring 托管 Bean,ID 为 sslConfig
.
Netty component (not http) also has a parameter ssl=true
. No idea if this is also needed for Netty-http。因此,您将不得不使用这些不同的参数进行一些测试。
顺便说一下,Netty 组件的文档有 an SSL example with context parameter configuration 等等。看看吧。
已解决。缺少自签名证书所需的一些说明。 下面是完整的bean。
@Bean(name = "sslContextParameters")
public static SSLContextParameters sslParameters() throws KeyManagementException, GeneralSecurityException, IOException {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("C:/myfolder/test.jks");
ksp.setPassword("jskPassword");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("jskPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLContext sslcontext = builder.build();
scp.createSSLContext().setDefault(sslcontext);
// Necessary for the the self-signed server certificate
TrustManagersParameters tmp = new TrustManagersParameters();
tmp.setKeyStore(ksp);
scp.setTrustManagers(tmp);
return scp;
}
至于 test.jks
文件,我使用 keytool
创建了它,该工具随 JDK
一起提供,用于管理证书(创建、导出和导入)。
在我已经使用 OpenSSL
创建证书的情况下,我只需要创建要导入的 JKS (Java Keystore)
文件。因为需要在 P12
文件中转换证书(它应该是一个存档),最后在 JKS
.
在操作过程中,您将被要求输入两个文件的密码
- openssl pkcs12 -export -in test.crt -inkey test.key -out test.p12
- keytool -importkeystore -srckeystore test.p12 -destkeystore test.jks -srcstoretype pkcs12
- keytool -importkeystore -srckeystore test.jks -destkeystore test.jks -deststoretype pkcs12
这里test是我的证书文件名。最后一个操作不是强制性的,但 keytool 本身建议将 JKS
格式(如果我理解正确的话是专有格式)迁移到更常见的 PKCS12
格式。
代码中的值jskPassword
是我在创建keystore时设置的密码
希望对你有所帮助。