使用spring-security更改方法调用的安全性上下文

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用spring-security更改方法调用的安全性上下文相关的知识,希望对你有一定的参考价值。

目前我正在使用spring security和@PreAuthorize注释来保护方法调用。现在我想更改方法调用的身份验证令牌,例如spring security的run-as authentication replacement允许我这样做。

我可以在每个方法基础上配置替换吗?每个注释,SpEL表达式....如果没有,是否可以在runAsManager中弄清楚调用什么方法?我如何配置安全对象的安全配置属性呢?

答案

我已经发布a detailed article@PreAuthorize一起实施Run-As。

1)实现自己的RunAsManager,创建Authentication,以便在方法执行期间根据任何自定义逻辑使用。以下示例使用提供额外角色的自定义注释:

public class AnnotationDrivenRunAsManager extends RunAsManagerImpl {

        @Override
        public Authentication buildRunAs(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
            if(!(object instanceof ReflectiveMethodInvocation) || ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class) == null) {
                return super.buildRunAs(authentication, object, attributes);
            }

            String roleName = ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class).value();

            if (roleName == null || roleName.isEmpty()) {
                return null;
            }

            GrantedAuthority runAsAuthority = new SimpleGrantedAuthority(roleName);
            List<GrantedAuthority> newAuthorities = new ArrayList<GrantedAuthority>();
            // Add existing authorities
            newAuthorities.addAll(authentication.getAuthorities());
            // Add the new run-as authority
            newAuthorities.add(runAsAuthority);

            return new RunAsUserToken(getKey(), authentication.getPrincipal(), authentication.getCredentials(),
                    newAuthorities, authentication.getClass());
        }
    }

此实现将在受保护的方法(例如@RunAsRole)上查找自定义@RunAsRole("ROLE_AUDITOR")注释,如果找到,将在给定的权限列表中添加给定的权限(在本例中为ROLE_AUDITOR)。 RunAsRole本身只是一个简单的自定义注释。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunAsRole {
    String value();
}

2)实例化经理:

<bean id="runAsManager"
    class="org.springframework.security.access.intercept.RunAsManagerImpl">
  <property name="key" value="my_run_as_key"/>
</bean>

3)注册:

<global-method-security pre-post-annotations="enabled" run-as-manager-ref="runAsManager">
    <expression-handler ref="expressionHandler"/>
</global-method-security>

4)控制器中的示例用法:

@Controller
public class TransactionLogController {

   @PreAuthorize("hasRole('ROLE_REGISTERED_USER')") //Authority needed to access the method
   @RunAsRole("ROLE_AUDITOR") //Authority added by RunAsManager
   @RequestMapping(value = "/transactions",  method = RequestMethod.GET) //Spring MVC configuration. Not related to security
   @ResponseBody //Spring MVC configuration. Not related to security
   public List<Transaction> getTransactionLog(...) {
    ... //Invoke something in the backend requiring ROLE_AUDITOR
   {

   ... //User does not have ROLE_AUDITOR here
}

编辑:keyRunAsManagerImpl的价值可以是你想要的任何东西。以下是Spring docs关于其使用的摘录:

为了确保恶意代码不会创建RunAsUserToken并将其呈现为RunAsImplAuthenticationProvider保证接受,密钥的散列将存储在所有生成的令牌中。 RunAsManagerImplRunAsImplAuthenticationProvider在bean上下文中使用相同的键创建:

<bean id="runAsManager"
    class="org.springframework.security.access.intercept.RunAsManagerImpl">

<bean id="runAsAuthenticationProvider"
    class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider">

通过使用相同的密钥,每个RunAsUserToken可以验证它是由批准的RunAsManagerImpl创建的。出于安全原因,RunAsUserToken在创建后是不可变的。

另一答案

我通过实现自己的RunAsManager来解决这个问题,qazxswpoi检查调用方法的自定义注释并返回相应的Token。

效果很好。

以上是关于使用spring-security更改方法调用的安全性上下文的主要内容,如果未能解决你的问题,请参考以下文章

在 spring-security 中更改 csrf 令牌

如何在spring-security的SecurityContext中存储自定义信息?

Spring-Security-文档笔记之认证组件

Spring-security 阻止匿名用户从 MongoDB 中提取数据

Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置

有啥方法可以强制在 spring-security 中的某些页面使用 https 吗?