16.3. 使用 Elytron 配置 Jakarta 身份验证安全性
从 JBoss EAP 7.3 开始,elytron
子系统从 Jakarta 身份验证中提供了 Servlet
配置集的实施。这样可以更紧密地与 Elytron 提供的安全功能集成。
为 Web 应用程序启用 Jakarta 身份验证
若要为 Web 应用启用 Jakarta 身份验证集成,需要将 Web 应用与 Elytron http-authentication-factory
或 security-domain
关联。通过这样做,可以为部署安装 Elytron 安全处理程序,并且为部署激活 Elytron 安全框架。
为部署激活 Elytron 安全框架时,会在处理请求时查询全局注册的 AuthConfigFactory
。它将识别用于该部署的 AuthConfigProvider
是否已注册。如果找到了 AuthConfigProvider
,则将使用 JASPI 身份验证,而不是部署的身份验证配置。如果找不到 AuthConfigProvider
,则将改为使用部署的身份验证配置。这可能会导致三种可能性之一:
-
使用
http-authentication-factory
中的身份验证机制. -
使用
web.xml 中指定的机制.
- 如果应用尚未定义任何机制,则不执行身份验证。
对 AuthConfigFactory
进行的任何更新都会立即可用。这意味着,如果注册了 a AuthConfigProvider
,并且与现有应用匹配,它将立即开始使用,而无需重新部署应用。
部署到 JBoss EAP 的所有 Web 应用都有一个安全域,将按照以下顺序解决:
- (来自部署描述符或注释)。
-
undertow
子系统的 default-security-domain
属性上定义的值。 -
默认为
其他
.
假定此安全域是对 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 身份验证集成的最小步骤是:
-
将
undertow
子系统上的default-security-domain
属性保留为未定义,以使其默认为other
。 -
添加从其他
到
Elytron 安全域的application-security-domain
映射。
下列步骤中与部署关联的安全域是安全域,它将包装到要 传递到
用于身份验证的 ServerAuthModule
实例中。
其他选项
在 application-security-domain
资源中添加了两个额外的属性,以便进一步控制 Jakarta 身份验证行为。
属性 | 描述 |
---|---|
|
可以设置为 |
|
默认情况下,所有身份都是从安全域加载的。如果设为 |
子系统配置
要注册将导致 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
资源的配置,传递到 ServerAuthModule
的 CallbackHandler
可在以下任一模式下运行:
集成模式
在集成模式下操作时,尽管 ServerAuthModule
实例将处理实际身份验证,但使用该 SecurityDomain 引用的 Security
中加载生成的身份 Realms,从引用的 Security
Domain。
在这种模式中,仍可以覆盖要在 servlet 容器中分配的角色。
此模式的优势在于,ServerAuthModules
能够利用 Elytron 配置来加载身份,从而无需了解这些位置即可加载存储在常规位置的身份 ,
如数据库和 LDAP。此外,还可以应用其他 Elytron 配置,如角色和权限映射。引用的 SecurityDomain
也可以在其他位置引用,如 SASL 身份验证或其他非 JASPI 应用,它们都由一个通用的身份存储库支持。
操作 | 描述 |
---|---|
|
用户名和密码将与 |
|
此 注意
如果已通过
如果收到带有 null Principal 和名称的
在执行对匿名身份的授权时, |
|
在这种模式中,使用安全域中配置的属性加载、角色解码和角色映射来建立身份。如果收到此 |
不集成模式
在非集成模式下运行时,ServerAuthModules
完全负责所有身份验证和身份管理。指定 的回调
可用于建立身份。生成的身份将在 SecurityDomain
上创建,但它独立于存储在引用的 SecurityRealms 中的任何身份
。
此模式的优势在于,完全处理身份的 JASPI 配置可以部署到应用服务器,而无需简单的 SecurityDomain 定义
。此 SecurityDomain
不需要实际包含运行时将使用的身份。此模式的缺点在于,ServerAuthModule
现在负责所有身份处理,可能会导致实施更加复杂。
操作 | 描述 |
---|---|
|
此模式中不支持 |
|
此
如果使用 null Principal 和 name 收到 |
|
由于该身份是在未从 |
validateRequest
在调用 ServerAuthContext
上的 validateRequest
期间,将按照定义的顺序调用各个 ServerAuthModule
实例。也可以为每个模块指定 control 标志。此标志定义应当如何解释响应,以及处理是否应继续进入下一个服务器身份验证模块或立即返回。
控制标记
无论配置是在 elytron
子系统内提供的,还是使用 JaspiConfigurationBuilder
API,都可将控制标志与每一 ServerAuthModule
关联。如果未指定,则默认为 REQUIRED
。标志具有以下含义,具体取决于它们的结果:
标记 | AuthStatus.SEND_SUCCESS | AuthStatus.SEND_FAILURE, AuthStatus.SEND_CONTINUE |
---|---|---|
必填 | 验证将继续至其余模块。只要满足其余模块的要求,该请求将被允许继续授权。 | 验证将继续至其余模块;但是,无论它们的结果如何,验证都无法成功,控制也会返回到客户端。 |
必需 | 验证将继续至其余模块。只要满足其余模块的要求,该请求将被允许继续授权。 | 请求将立即返回到客户端。 |
足够 |
验证被认定为成功且已完成,如果以前的 |
验证将继续向下列出剩余模块。只有没有 |
选填 |
只要任何 |
验证将继续向下列出剩余模块。只有没有 |
对于所有 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.SecurityIdentityIdentityCallbacks
,这是直接从 SecurityDomain
加载的身份,也可以是回调描述的临时身份。此 安全身份将与
请求相关联,方式与其它验证机制相同。