16.4.3. 配置资源适配器以使用 Elytron 子系统

在 IronJacamar 中的服务器和资源适配器之间有两种通信。

其中一个是服务器何时打开资源适配器连接。如规格中所定义,这可以通过容器管理的登录进行保护,这需要在打开连接时将 JAAS 主题及主体和凭证传播到资源适配器。此登录可委派给 Elytron。

IronJacamar 支持安全性内流。这种机制使得资源适配器能够在向工作管理器提交工作时,以及在将消息传送到驻留在同一 JBoss EAP 实例中的端点时建立安全信息。

容器管理的登录

若要通过 Elytron 实现容器管理的登录,需要将 elytron-enabled 属性设为 true。这将导致与 Elytron 保护的资源适配器的所有连接。

/subsystem=resource-adapters/resource-adapter=RAR_NAME/connection-definitions=FACTORY_NAME:write-attribute(name=elytron-enabled,value=true)

若要配置 elytron-enabled 属性,可以使用管理 CLI 将 resource -adapters 子系统中的 elytron- enabled 属性设置为 true。默认情况下,此属性设为 false

authentication-context 属性定义要用于执行登录的 Elytron 身份验证上下文的名称。

Elytron authentication-context 属性可以包含一个或多个 身份验证配置 元素,后者包含您要使用的凭据。

如果未设置 authentication-context 属性,JBoss EAP 将使用当前的 authentication-context,这是供开启 连接的调用者代码使用的 authentication- context。

示例:创建 身份验证配置

/subsystem=elytron/authentication-configuration=exampleAuthConfig:add(authentication-name=sa,credential-reference={clear-text=sa})

示例:使用上述配置创建 authentication-context

/subsystem=elytron/authentication-context=exampleAuthContext:add(match-rules=[{authentication-configuration=exampleAuthConfig}])

安全流

资源管理器也可以在提交将由工作管理器执行的工作时引入安全凭据。安全进流允许工作在执行前对自身进行身份验证。如果身份验证成功,则提交的工作将在生成的身份验证上下文下执行。如果失败,则工作执行将被拒绝。

要启用 Elytron 安全内流,请在配置资源适配器工作管理器时设置 wm-elytron-security-domain 属性。Elytron 将根据指定的域执行身份验证。

注意

当资源适配器工作管理器配置为使用 Elytron 安全域 wm-elytron-security-domain 时,引用的工作管理器应将 elytron-enabled 属性设为 true

/subsystem=jca/workmanager=customWM:add(name=customWM, elytron-enabled=true)
注意

如果使用 wm-security-domain 属性而不是 wm-elytron -security-domain 属性,则安全流将由传统 安全 子系统来执行。

在下面 jca 子系统的示例配置中,我们可以看到名为 ra-with-elytron-security-domain 的资源适配器的配置。此资源适配器将工作管理器安全性配置为使用 Elytron 安全域的 wm-realm

<subsystem xmlns="urn:jboss:domain:jca:5.0">
    <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
    <bean-validation enabled="true"/>
    <default-workmanager>
        <short-running-threads>
            <core-threads count="50"/>
            <queue-length count="50"/>
            <max-threads count="50"/>
            <keepalive-time time="10" unit="seconds"/>
        </short-running-threads>
        <long-running-threads>
            <core-threads count="50"/>
            <queue-length count="50"/>
            <max-threads count="50"/>
            <keepalive-time time="10" unit="seconds"/>
        </long-running-threads>
    </default-workmanager>
    <workmanager name="customWM">
        <elytron-enabled>true</elytron-enabled>
        <short-running-threads>
            <core-threads count="20"/>
            <queue-length count="20"/>
            <max-threads count="20"/>
        </short-running-threads>
    </workmanager>
    <bootstrap-contexts>
        <bootstrap-context name="customContext" workmanager="customWM"/>
    </bootstrap-contexts>
    <cached-connection-manager/>
</subsystem>

然后,使用 resource-adapter 子系统中的 boostrap 上下文引用工作管理器。

<subsystem xmlns="urn:jboss:domain:resource-adapters:5.0">
    <resource-adapters>
        <resource-adapter id="ra-with-elytron-security-domain">
            <archive>
                ra-with-elytron-security-domain.rar
            </archive>
            <bootstrap-context>customContext</bootstrap-context>
            <transaction-support>NoTransaction</transaction-support>
            <workmanager>
                <security>
                    <elytron-security-domain>wm-realm</elytron-security-domain>
                    <default-principal>wm-default-principal</default-principal>
                    <default-groups>
                        <group>
                            wm-default-group
                        </group>
                    </default-groups>
                </security>
            </workmanager>
        </resource-adapter>
    </resource-adapters>
</subsystem>

示例:安全域的配置

/subsystem=elytron/properties-realm=wm-properties-realm:add(users-properties={path=/security-dir/users.properties, plain-text=true}, groups-properties={path=/security-dir/groups.properties})

/subsystem=elytron/simple-role-decoder=wm-role-decoder:add(attribute=groups)

/subsystem=elytron/constant-permission-mapper=wm-permission-mapper:add(permissions=[{class-name="org.wildfly.security.auth.permission.LoginPermission"}])

/subsystem=elytron/security-domain=wm-realm:add(default-realm=wm-properties-realm, permission-mapper=wm-permission-mapper, realms=[{role-decoder=wm-role-decoder, realm=wm-properties-realm}])

Work 类负责提供指定域下 Elytron 身份验证的凭据。为此,它必须实施 javax.resource.spi.work.WorkContextProvider

public interface WorkContextProvider {
   /**
    * Gets an instance of <code>WorkContexts</code> that needs to be used
    * by the <code>WorkManager</code> to set up the execution context while
    * executing a <code>Work</code> instance.
    *
    * @return an <code>List</code> of <code>WorkContext</code> instances.
    */
   List<WorkContext> getWorkContexts();
}

此界面允许 工作 类使用 WorkContext 来配置要在其中执行任务的上下文的某些方面。其中一个方面是安全进化。为此,List<WorkContext> getWorkContexts 方法必须提供 javax.resource.spi.work.SecurityContext。此上下文将使用 JSR-196 规范 中定义的 javax.security.auth.callback.Callback 对象来提供凭据。用于容器服务供应商接口身份验证的 Jakarta 等同于 Jakarta 身份验证

示例:使用上下文创建回调

public class ExampleWork implements Work, WorkContextProvider {

    private final String username;
    private final String role;

    public MyWork(TestBean bean, String username, String role) {
        this.principals = null;
        this.roles = null;
        this.bean = bean;
        this.username = username;
        this.role = role;
    }

    public List<WorkContext> getWorkContexts() {
        List<WorkContext> l = new ArrayList<>(1);
        l.add(new MySecurityContext(username, role));
        return l;
    }

    public void run() {
        ...
    }

    public void release() {
        ...
    }

    public class ExampleSecurityContext extends SecurityContext {

        public void setupSecurityContext(CallbackHandler handler, Subject executionSubject, Subject serviceSubject) {
            try {
                List<javax.security.auth.callback.Callback> cbs = new ArrayList<>();
                cbs.add(new CallerPrincipalCallback(executionSubject, new SimplePrincipal(username)));
                cbs.add(new GroupPrincipalCallback(executionSubject, new String[]{role}));
                handler.handle(cbs.toArray(new javax.security.auth.callback.Callback[cbs.size()]));
            } catch (Throwable t) {
                throw new RuntimeException(t);
            }
        }
    }

在上例中,Examp leWork 实施 WorkContextProvider 接口来提供 ExampleSecurityContext。该上下文将创建必要的回调,以提供 Elytron 在工作执行时验证的安全信息。