2012-07-26 55 views
6

当前我正在使用spring security和@PreAuthorize注释来保护方法调用。现在我想改变一个方法调用的认证标记,就像Spring安全允许我做的run-as authentication replacement一样。用spring-security更改方法调用的安全上下文

我可以在每个方法基础上配置替换吗?每注释,SpEL表达式.... 如果没有,是否有可能在runAsManager中计算出哪种方法被调用? 我将如何配置安全对象的安全配置属性?

回答

1

我通过实现我自己的RunAsManager解决了这个问题,它检查被调用方法上的自定义注释并返回相应的令牌。

很好用。

6

我已经发布a detailed article实施运行与@PreAuthorize结合。

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 
} 

编辑:RunAsManagerImpl中的值可以是任何你想要的。下面是Spring docs其使用的摘录:

为了确保恶意代码不会创建一个关键的RunAsUserToken和现在 它保证接受的RunAsImplAuthenticationProvider, 散列被存储在所有生成的标记。该 RunAsManagerImplRunAsImplAuthenticationProvider在 豆上下文中创建具有相同的键:

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

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

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

+0

“my_run_as_key”的用途是什么? - 我无法弄清楚。我可能读过你在这里引用的同一个指南,但这个关键对我没有任何意义。 – 2016-12-12 11:07:39

+0

@DanielBo值可以是任何你想要的。它基本上是一个密码。 我更新了为什么需要引用Spring文档的答案。 – kaqqao 2016-12-12 14:34:27

相关问题