EAP:使用 elytron client-ssl-context 创建 REST 客户端

问题描述 投票:0回答:2

我知道,如何使用自己的 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 初学者的任何提示。 预先感谢。

jboss resteasy
2个回答
1
投票

有一个 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());

0
投票

我找到了另一个解决方案:

我在 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),这个逻辑也将起作用

© www.soinside.com 2019 - 2024. All rights reserved.