我知道,如何使用自己的 SSL 上下文构建 ResteasyClient。
builder.sslContext(mySSLcontext);
它工作正常,例如来自独立客户端和/或 arquiillain 测试。 我以编程方式构建 SSL 上下文,加载信任库等。
我有一个 EAR+War (ProjekctA),它使用 web.xml 提供 Rest 服务:
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>ICSCRest</realm-name>
</login-config>
和jboss-web.xml
<jboss-web>
<server-instance>default-server</server-instance>
<virtual-host>default-host</virtual-host>
<security-domain>ICSDRest</security-domain>
</jboss-web>
EAP(7.4.7)配置有Elytron,提供安全域(ICSDRest)。 工作正常。对 Rest 服务的访问现在由 SSL 层保护。 我还配置了 EAP 以具有 client-ssl-context(请参阅下面的 LDAP)。
<client-ssl-contexts>
<client-ssl-context name="ICLdapSslContext" trust-manager="ICTrustManager"/>
</client-ssl-contexts>
第二个 EAR+War (ProjectB) 应使用 ProjectA 的 Rest 服务。所以 ProjectB 是一个 Rest 客户端。
要在 ProjectB 中实例化 ResteasyClient,我也必须设置 sslContext(我猜)。 如果可能的话,我想从 Elytron 选择一个 client-ssl-context。 有办法吗?
为什么我想选择 Elytron?
ProjectA 还通过 ldaps 处理 LDAP。所以 ProjectA 是 LDAP 服务器的客户端。 我已将 EAP 配置为 LDAP 客户端,例如
<dir-contexts>
<dir-context name="ICLdap" url="<some url>" principal="<query>" ssl-context="ICLdapSslContext">
<credential-reference clear-text="<some password>"/>
</dir-context>
</dir-contexts>
所以我希望,我能以类似的方式从 EAP/Elytron 获得 sslContext。 这个想法是从 Elytron 获取 SSL 上下文并设置为
builder.sslContext(mySSLcontext)
或在上下文中创建 ReasteasyClient。
给 EAP 初学者的任何提示。 预先感谢。
有一个 elytron Java 安全提供程序,可用于通过 SSLContext.getDefault() 调用获取 elytron SSLContext。这篇博客文章对此进行了描述:https://wildfly-security.github.io/wildfly-elytron/blog/client-default-ssl-context/
因此,在您的设置中,也许您可以创建一个 elytron 客户端配置文件 wildfly-config.xml ,您可以在其中指定具有与“ICTrustManager”使用的相同信任管理器配置的 ssl 上下文。然后,您可以向提供者提供此配置文件的路径。例如在这样的代码中:
Security.insertProviderAt(new WildFlyElytronClientDefaultSSLContextProvider(CONFIG_FILE_PATH), 1);
然后你可以为你的 ResteasyClient 配置它:
builder.sslContext(SSLContext.getDefault());
我找到了另一个解决方案:
我在 ProjectB 中为 REST 客户端创建了一个新密钥。
keytool -genkey -keystore projectB-client.p12 ...
keytool -exportcert -keystore projectB-client.p12 ...
将项目A的JBoss/EAP中的公钥添加到项目B-client.p12
keytool -keystore projectB-client.p12 -importcert -trustcacerts ...
密钥库项目B-client.p12放置在EAP独立/配置目录中。
将projectB-client.p12中的公钥添加到JBoss/EAP的信任库中
keytool -keystore app.truststore -importcert -trustcacerts ....
通过 Jboss CLI,我添加了一个新的安全域。
/subsystem=security/security-domain=projectB-client:add
/subsystem=security/security-domain=projectB-client/jsse=classic:add(truststore={password=<...>,url="file:${jboss.server.config.dir}/app.truststore"}, \
keystore={password=<...>, url="file:${jboss.server.config.dir}/projectB-client.p12"}, client-auth=true)
这将创建一个类似以下的条目:
<security-domains>
...
<security-domain name="projectB-client">
<jsse keystore-password="password here" keystore-url="file:${jboss.server.config.dir}/projectB-client.p12" truststore-password="password here" truststore-url="file:${jboss.server.config.dir}/app.truststore" client-auth="true"/>
</security-domain>
</security-domains>
在 ProjectB 中,以下代码将从 EAP 请求安全域并获取密钥管理器和 trusmanager 的访问权限,而无需两者的任何密码。
例如
@ApplicationScoped
public class InitalizerOnStartup {
private MyService myService;
public void onStart(@Observes @Initialized(ApplicationScoped.class) Object pointless) throws Exception {
buildICRestClient();
}
private void buildICRestClient () throws Exception {
final String sdName = "java:jboss/jaas/projectB-client/jsse";
final URL endPoint = new URL("https://localhost:8443/myUrl");
Context ctx = new InitialContext();
JBossJSSESecurityDomain sd = (JBossJSSESecurityDomain) ctx.lookup(sdName);
if ( sd == null )
throw new Exception("Can't get EAP security domain - name=" + sdName);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(sd.getKeyManagers(), sd.getTrustManagers(), null);
ResteasyClientBuilder builder = new ResteasyClientBuilder();
builder.sslContext(sslContext);
ResteasyClient client = builder.build();
ResteasyWebTarget target = client.target(endPoint.toURI());
myService = target.proxy(MyService.class);
}
}
或使用 EBJ 技术
@Startup
。
我想,当 ProjectA + B 位于不同的服务器上时(使用 localhost -> fqdn),这个逻辑也将起作用