运行中的认证替换
本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
在 secure 对象回调阶段,AbstractSecurityInterceptor
能够暂时替换 SecurityContext
和 SecurityContextHolder
中的 Authentication
对象。这只发生在原始 Authentication
对象被 AuthenticationManager
和 AccessDecisionManager
成功处理的情况下。RunAsManager
指出在 SecurityInterceptor
回调期间应该使用的替换 Authentication
对象(如果有的话)。
通过在secure对象回调阶段临时替换 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
支持安全拦截器提出的 secure 对象的类型。
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
保证接受,所有生成的token中都存储了一个密钥的哈希值。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
在创建后是不可改变的。