运行时身份验证替换
AbstractSecurityInterceptor
能够在安全对象回调阶段临时替换 SecurityContext
和 SecurityContextHolder
中的 Authentication
对象。这仅在原始 Authentication
对象已成功由 AuthenticationManager
和 AccessDecisionManager
处理的情况下才会发生。RunAsManager
指示在 SecurityInterceptorCallback
期间应使用的替换 Authentication
对象(如果有)。
通过在安全对象回调阶段临时替换 Authentication
对象,安全调用可以调用需要不同身份验证和授权凭据的其他对象。它还可以对特定 GrantedAuthority
对象执行任何内部安全检查。由于 Spring Security 提供了许多帮助程序类,这些类根据 SecurityContextHolder
的内容自动配置远程协议,因此这些运行时替换在调用远程 Web 服务时特别有用。
配置
Spring Security 提供了一个 RunAsManager
接口
Authentication buildRunAs(Authentication authentication, Object object,
List<ConfigAttribute> config);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
第一个方法返回在方法调用期间应替换现有 Authentication
对象的 Authentication
对象。如果该方法返回 null
,则表示不应进行替换。第二个方法由 AbstractSecurityInterceptor
用作其配置属性启动验证的一部分。supports(Class)
方法由安全拦截器实现调用,以确保配置的 RunAsManager
支持安全拦截器提供的安全对象类型。
Spring Security 提供了一个 RunAsManager
的具体实现。如果任何 ConfigAttribute
以 RUN_AS_
开头,则 RunAsManagerImpl
类将返回一个替换的 RunAsUserToken
。如果找到任何此类 ConfigAttribute
,则替换的 RunAsUserToken
将包含与原始 Authentication
对象相同的 principal、凭据和授予的权限,以及每个 RUN_AS_
ConfigAttribute
的新的 SimpleGrantedAuthority
。每个新的 SimpleGrantedAuthority
以 ROLE_
为前缀,后跟 RUN_AS
ConfigAttribute
。例如,RUN_AS_SERVER
会导致替换的 RunAsUserToken
包含 ROLE_RUN_AS_SERVER
授予的权限。
替换的 RunAsUserToken
与任何其他 Authentication
对象一样。它需要由 AuthenticationManager
进行身份验证,可能是通过委托给合适的 AuthenticationProvider
。RunAsImplAuthenticationProvider
执行此类身份验证。它接受作为有效的任何呈现的 RunAsUserToken
。
为了确保恶意代码不会创建 RunAsUserToken
并将其呈现以供 RunAsImplAuthenticationProvider
保证接受,密钥的哈希值存储在所有生成的令牌中。RunAsManagerImpl
和 RunAsImplAuthenticationProvider
在 bean 上下文中使用相同的密钥创建
<bean id="runAsManager"
class="org.springframework.security.access.intercept.RunAsManagerImpl">
<property name="key" value="my_run_as_password"/>
</bean>
<bean id="runAsAuthenticationProvider"
class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider">
<property name="key" value="my_run_as_password"/>
</bean>
通过使用相同的密钥,每个 RunAsUserToken
都可以被验证,因为它是由经过批准的 RunAsManagerImpl
创建的。出于安全原因,RunAsUserToken
在创建后是不可变的。