# run-as 身份验证替换
# 概述
在安全对象回调阶段,AbstractSecurityInterceptor
可以在SecurityContext
和SecurityContextHolder
中临时替换Authentication
对象。只有当原始Authentication
对象被AuthenticationManager
和AccessDecisionManager
成功处理时,才会发生这种情况。RunAsManager
将指示在SecurityInterceptorCallback
期间应该使用的替换Authentication
对象(如果有的话)。
通过在安全对象回调阶段临时替换Authentication
对象,安全调用将能够调用需要不同身份验证和授权凭据的其他对象。它还能够对特定的GrantedAuthority
对象执行任何内部安全检查。因为 Spring Security 提供了许多帮助器类,这些帮助器类根据SecurityContextHolder
的内容自动配置远程协议,所以在调用远程 Web 服务时,这些 run-as 替换特别有用。
# 配置
一个RunAsManager
接口由 Spring Security 提供:
Authentication buildRunAs(Authentication authentication, Object object,
List<ConfigAttribute> config);
boolean supports(ConfigAttribute attribute);
boolean supports(Class clazz);
第一个方法返回Authentication
对象,该对象应该在方法调用的持续时间内替换现有的Authentication
对象。如果该方法返回null
,则表示不应进行替换。第二种方法由AbstractSecurityInterceptor
使用,作为其配置属性的启动验证的一部分。安全拦截器实现调用supports(Class)
方法,以确保配置的RunAsManager
支持安全拦截器将呈现的安全对象类型。
一个RunAsManager
的具体实现提供了 Spring 安全性。RunAsManagerImpl
类返回一个替换RunAsUserToken
,如果有ConfigAttribute
以RUN_AS_
开头。如果找到任何这样的ConfigAttribute
,则替换的RunAsUserToken
将包含与原始Authentication
对象相同的主体、凭据和授予的权限,以及每个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
,密钥的散列存储在所有生成的令牌中。在 Bean 上下文中使用相同的键创建RunAsManagerImpl
和RunAsImplAuthenticationProvider
:
<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
在创建后是不可变的