16.3. 使用 Elytron 配置 Jakarta 身份验证安全性


从 JBoss EAP 7.3 开始,elytron 子系统从 Jakarta 身份验证中提供了 Servlet 配置集的实施。这样可以更紧密地与 Elytron 提供的安全功能集成。

为 Web 应用程序启用 Jakarta 身份验证

若要为 Web 应用启用 Jakarta 身份验证集成,需要将 Web 应用与 Elytron http-authentication-factorysecurity-domain 关联。通过这样做,可以为部署安装 Elytron 安全处理程序,并且为部署激活 Elytron 安全框架。

为部署激活 Elytron 安全框架时,会在处理请求时查询全局注册的 AuthConfigFactory。它将识别用于该部署的 AuthConfigProvider 是否已注册。如果找到了 AuthConfigProvider,则将使用 JASPI 身份验证,而不是部署的身份验证配置。如果找不到 AuthConfigProvider,则将改为使用部署的身份验证配置。这可能会导致三种可能性之一:

  • 使用 http-authentication-factory 中的身份验证机制.
  • 使用 web.xml 中指定的机制.
  • 如果应用尚未定义任何机制,则不执行身份验证。

AuthConfigFactory 进行的任何更新都会立即可用。这意味着,如果注册了 a AuthConfigProvider,并且与现有应用匹配,它将立即开始使用,而无需重新部署应用。

部署到 JBoss EAP 的所有 Web 应用都有一个安全域,将按照以下顺序解决:

  1. (来自部署描述符或注释)。
  2. undertow 子系统 的 default-security-domain 属性上定义的值。
  3. 默认为 其他.
注意

假定此安全域是对 PicketBox 安全域的引用,因此激活的最后一步是确保在 undertow 子系统中使用 application-security-domain 资源将它映射到 Elytron。

此映射可执行以下操作之一:

  • 直接引用 elytron 安全域,例如:

    /subsystem=undertow/application-security-domain=MyAppSecurity:add(security-domain=ApplicationDomain)
  • 引用 http-authentication-factory 资源来获取身份验证机制的实例,例如:

    /subsystem=undertow/application-security-domain=MyAppSecurity:add(http-authentication-factory=application-http-authentication)

启用 Jakarta 身份验证集成的最小步骤是:

  1. undertow 子系统上的 default-security-domain 属性保留为未定义,以使其默认为 other
  2. 添加从其他 Elytron 安全域的 application-security-domain 映射。

下列步骤中与部署关联的安全域是安全域,它将包装到要 传递到 用于身份验证的 ServerAuthModule 实例中。

其他选项

application-security-domain 资源中添加了两个额外的属性,以便进一步控制 Jakarta 身份验证行为。

表 16.1. 添加到 application-security-domain 资源的属性
属性描述

enable-jaspi

可以设置为 false,以使用此映射为所有部署禁用 Jakarta 身份验证支持。

integrated-jaspi

默认情况下,所有身份都是从安全域加载的。如果设为 false,则会改为创建 ad-hoc 身份。

子系统配置

要注册将导致 AuthConfigProvider 返回部署的配置,一种方法是在 elytron 子系统中注册 jaspi-configuration

以下命令演示了如何添加包含两个 ServerAuth 模块定义的配置

/subsystem=elytron/jaspi-configuration=simple-configuration:add(layer=HttpServlet, application-context="default-host /webctx", description="Elytron Test Configuration", server-auth-modules=[{class-name=org.wildfly.security.examples.jaspi.SimpleServerAuthModule, module=org.wildfly.security.examples.jaspi, flag=OPTIONAL, options={a=b, c=d}}, {class-name=org.wildfly.security.examples.jaspi.SecondServerAuthModule, module=org.wildfly.security.examples.jaspi}])

这将永久保留以下配置:

<jaspi>
    <jaspi-configuration name="simple-configuration" layer="HttpServlet" application-context="default-host /webctx" description="Elytron Test Configuration">
        <server-auth-modules>
            <server-auth-module class-name="org.wildfly.security.examples.jaspi.SimpleServerAuthModule" module="org.wildfly.security.examples.jaspi" flag="OPTIONAL">
                <options>
                    <property name="a" value="b"/>
                    <property name="c" value="d"/>
                </options>
            </server-auth-module>
            <server-auth-module class-name="org.wildfly.security.examples.jaspi.SecondServerAuthModule" module="org.wildfly.security.examples.jaspi"/>
        </server-auth-modules>
    </jaspi-configuration>
</jaspi>
注意

name 属性只是允许在管理模型中引用资源的名称。

和应用上下文 属性用于将此配置注册到 AuthConfigFactory。可以省略这两个属性,允许通配符匹配。description 属性也是可选的,用于向 AuthConfigFactory 提供描述。

在 配置中,可以使用下列属性定义一个或多个 server-auth-module 实例:

  • class-name - ServerAuthModule 的完全限定类名称。
  • 模块 - 要从中加载 ServerAuthModule 的模块。
  • 标志 - 用于指示此模块如何与其他模块相比运行的控制标志。
  • 选项 - 初始化时要传递到 服务器AuthModule 中的配置选项。

以这种方式定义的配置立即注册到 AuthConfigFactory。任何使用与 和应用上下文 匹配的 Elytron 安全框架的现有部署都将立即开始使用此配置。

编程配置

Jakarta 身份验证规范中定义的 API 允许应用程序动态注册 custom AuthConfigProvider 实例。但是,该规范不提供要使用的实际实施,也不提供创建实现实例的任何标准方法。Elytron 项目包含一个简单的实用程序,可供部署用于帮助实现此目标。

以下代码示例演示了如何使用此 API 注册与上述子系统配置中所示的配置类似的配置

String registrationId = org.wildfly.security.auth.jaspi.JaspiConfigurationBuilder.builder("HttpServlet", servletContext.getVirtualServerName() + " " + servletContext.getContextPath())
    .addAuthModuleFactory(SimpleServerAuthModule::new, Flag.OPTIONAL, Collections.singletonMap("a", "b"))
    .addAuthModuleFactory(SecondServerAuthModule::new)
.register();

例如,此代码可以在 Servlet 的 init() 方法中执行,以注册特定于该 部署的AuthConfigProvider。在此代码示例中,还通过咨询 ServletContext 汇编了应用程序上下文。

register() 方法返回生成的注册 ID,这也可用于直接从 AuthConfigFactory 中删除此注册。

Subsystem 配置一样,此调用也立即生效,适用于所有使用 Elytron 安全框架的 Web 应用。

身份验证过程

根据 undertow 子系统中 application-security-domain 资源的配置,传递到 ServerAuthModuleCallbackHandler 可在以下任一模式下运行:

集成模式

在集成模式下操作时,尽管 ServerAuthModule 实例将处理实际身份验证,但使用该 SecurityDomain 引用的 Security Realms,从引用的 Security Domain 中加载生成的身份 在这种模式中,仍可以覆盖要在 servlet 容器中分配的角色。

此模式的优势在于,ServerAuthModules 能够利用 Elytron 配置来加载身份,从而无需了解这些位置即可加载存储在常规位置的身份 如数据库和 LDAP。此外,还可以应用其他 Elytron 配置,如角色和权限映射。引用的 SecurityDomain 也可以在其他位置引用,如 SASL 身份验证或其他非 JASPI 应用,它们都由一个通用的身份存储库支持。

表 16.2. 集成模式下 CallbackHandlers 方法的操作。
操作描述

PasswordValidationCallback

用户名和密码将与 SecurityDomain 一起使用,以执行身份验证。如果成功,将有一个经过身份验证的身份。

CallerPrincipalCallback

回调 用于建立授权身份或在请求到达 Web 应用后可用的身份。

注意

如果已通过 PasswordValidationCallback 建立了经过身份验证的身份,则此 Callback 将 解释为作为运行请求。在这种情况下,要执行授权检查,以确保身份验证的身份被授权以以此 回调 中指定的身份运行。如果 PasswordValidationCallback 没有建立经过身份验证的身份,则假定 ServerAuthModule 处理了身份验证步骤。

如果收到带有 null Principal 和名称的 回调,则:

  • 如果已经建立了经过身份验证的身份,则将以该身份执行授权。
  • 如果没有建立身份,将执行匿名身份的授权。

在执行对匿名身份的授权时,SecurityDomain 必须已配置为授予匿名身份的 LoginPermission

GroupPrincipalCallback

在这种模式中,使用安全域中配置的属性加载、角色解码和角色映射来建立身份。如果收到此 回调,则使用指定的组来确定分配给该身份的角色。请求将位于 servlet 容器中,这些角色仅在 servlet 容器中可见。

不集成模式

在非集成模式下运行时,ServerAuthModules 完全负责所有身份验证和身份管理。指定 的回调 可用于建立身份。生成的身份将在 SecurityDomain 上创建,但它独立于存储在引用的 SecurityRealms 中的任何身份

此模式的优势在于,完全处理身份的 JASPI 配置可以部署到应用服务器,而无需简单的 SecurityDomain 定义。此 SecurityDomain 不需要实际包含运行时将使用的身份。此模式的缺点在于,ServerAuthModule 现在负责所有身份处理,可能会导致实施更加复杂。

表 16.3. 在非集成模式下,CallbackHandlers 方法的操作。
操作描述

PasswordValidationCallback

此模式中不支持 Callback。此模式的目的是让 ServerAuthModule 独立于引用的 SecurityDomain 运行。请求验证密码并不合适。

CallerPrincipalCallback

回调 用于为生成的身份建立 Principal。由于 ServerAuthModule 正在处理所有身份检查要求,因此不会执行任何检查来验证安全域中是否存在身份并且不执行授权检查。

如果使用 null Principal 和 name 收到 Callback,则身份将作为匿名身份建立。由于 ServerAuthModule 正在做出决策,因此不会使用 SecurityDomain 执行授权检查。

GroupPrincipalCallback

由于该身份是在未从 SecurityDomain 加载的情况下创建的,所以默认情况下不会分配任何角色。如果收到此 回调,则在请求位于 servlet 容器中时,将生成组并分配给生成的身份。这些角色仅在 servlet 容器中可见。

validateRequest

在调用 ServerAuthContext 上的 validateRequest 期间,将按照定义的顺序调用各个 ServerAuthModule 实例。也可以为每个模块指定 control 标志。此标志定义应当如何解释响应,以及处理是否应继续进入下一个服务器身份验证模块或立即返回。

控制标记

无论配置是在 elytron 子系统内提供的,还是使用 JaspiConfigurationBuilder API,都可将控制标志与每一 ServerAuthModule 关联。如果未指定,则默认为 REQUIRED。标志具有以下含义,具体取决于它们的结果:

标记AuthStatus.SEND_SUCCESSAuthStatus.SEND_FAILURE, AuthStatus.SEND_CONTINUE

必填

验证将继续至其余模块。只要满足其余模块的要求,该请求将被允许继续授权。

验证将继续至其余模块;但是,无论它们的结果如何,验证都无法成功,控制也会返回到客户端。

必需

验证将继续至其余模块。只要满足其余模块的要求,该请求将被允许继续授权。

请求将立即返回到客户端。

足够

验证被认定为成功且已完成,如果以前的 Required 或 Requisite 模块没有返回 AuthStatus,但 AuthStatus.SUCCESS.请求将继续授权受保护的资源。

验证将继续向下列出剩余模块。只有没有 REQUIRED 或 REQUI SITE 模块时,这个状态才会影响决定。

选填

只要任何 所需的Requisite 模块尚未返回 SUCCESS,验证将继续对剩余的模块进行验证。这将足以使验证被视为成功,并使请求进入授权阶段和安全的资源。

验证将继续向下列出剩余模块。只有没有 REQUIRED 或 REQUI SITE 模块时,这个状态才会影响决定。

注意

对于所有 ServerAuthModule 实例,如果它们抛出 AuthException,则立即向客户端报告错误,而无需进一步调用模块。

secureResponse

在调用 secureResponse 时,调用每个 ServerAuthModule,但这一次以相反的顺序调用,其中模块仅在 secureResponse 中执行操作。如果模块强化了 validateResponse 中的 操作,则模块负责跟踪此操作。

control 标志对 secureResponse 处理 没有影响。当以下过程之一为 true 时,处理结束:

  • 所有 ServerAuthModule 实例都已调用。
  • 模块返回 AuthStatus.SEND_FAILURE
  • 模块抛出 AuthException.
SecurityIdentity Creation

身份验证过程完成后,由于 回调到 Call backHandler,将创建用于 部署的 SecurityDomain 的 org.wildfly.security.auth.server.SecurityIdentityIdentity。根据 Callbacks,这是直接从 SecurityDomain 加载的身份,也可以是回调描述的临时身份。此 安全身份将与 请求相关联,方式与其它验证机制相同。

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.