Spring Security提供了一个运行管理器界面:
1 Authentication buildRunAs(Authentication authentication, Object object, 2 List<ConfigAttribute> config); 3 4 boolean supports(ConfigAttribute attribute); 5 6 boolean supports(Class clazz);
第一个方法返回身份验证对象,该对象应该在方法调用期间替换现有的身份验证对象。如果该方法返回null,则表示不应进行任何替换。第二种方法由抽象安全接口AbstractSecurityInterceptor
使用,作为其配置属性启动验证的一部分。安全拦截器实现调用支持(类)方法,以确保配置的运行管理器RunAsManager
支持安全拦截器将呈现的安全对象类型。
运行管理器RunAsManager的一个具体实现是由Spring Security提供的。如果任何配置属性以RUN_AS_开头,则RunAsManagerImpl类将返回一个替换的RunAsUserToken。如果找到任何这样的配置属性,替换的运行身份验证将包含与原始身份验证对象相同的主体、凭据和授权,以及每个 RUN_AS_ 配置属性的新的简单授权认证。每一个新的SimpleGrantedAuthority 都将带ROLE_前缀,后跟RUN_AS 配置属性。例如,一个RUN_AS_SERVER 将导致替换RunAsUserToken 包含一个ROLE_RUN_AS_SERVER 授权。
替换RunAsUserToken 就像任何其他身份验证对象一样。它需要由身份验证管理器进行身份验证,可能通过委托给合适的身份验证提供程序AuthenticationProvider。RunasImplauthenticationProvider执行这种身份验证。它只是接受任何有效的RunAsUserToken 。
为了确保恶意代码不会创建运行时支持令牌RunAsUserToken 并将其提交给运行时身份验证提供程序RunAsImplAuthenticationProvider以保证其被接受,密钥的哈希会存储在所有生成的令牌中。RunAsManagerImpl和RunasImplauthenticationProvider是在bean上下文中用相同的键创建的:
1 <bean id="runAsManager" 2 class="org.springframework.security.access.intercept.RunAsManagerImpl"> 3 <property name="key" value="my_run_as_password"/> 4 </bean> 5 6 <bean id="runAsAuthenticationProvider" 7 class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> 8 <property name="key" value="my_run_as_password"/> 9 </bean>
通过使用相同的密钥,可以验证每个运行支持令牌RunAsUserToken 是否是由经过批准的运行管理器RunAsManagerImpl创建的。出于安全原因,RunAsUserToken在创建后是不可变的