使用注释和全局denyAll的Spring Security白名单方法

时间:2013-07-17 00:38:59

标签: spring spring-mvc spring-security annotations whitelist

目前,我试图弄清楚Spring Security如何评估给定的URL,表达式和注释。到目前为止,似乎总是首先检查来自security-context.xml的条目。如果那是denyAll,它将停止进一步处理请求。

也许我忘了设置一些配置选项,但(在我看来)使用Spring Security的注释(如@Secured@PermitAll等)构建一个漂亮的白名单是不可能的。

我想要的基本上是在@Controller内注释允许访问的方法。例如:

@Controller
@RequestMapping("/test")
public MyController {
    @RequestMapping("")
    public void tryToGetSomething() {
      // no security annotation -> denyAll
    }

    @RequestMapping("/public")
    @PermitAll
    public void tryToGetSomethingPublic() {
      // this will always have access allowed
    }

    @RequestMapping("/admin")
    @Secured({"ROLE_ADMIN"})
    public void tryToGetSomethingReallyImportant() {
      // this can only be accessed by admins
    }
}

这种方法的主要原因是:安全性;-)。在编写代码时总是可以忘记一些注释。使用这种方法,这样的错误不会影响敏感数据的安全性。

所以我的问题是:我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:0)

您可以尝试将安全切入点与注释结合使用:

<global-method-security pre-post-annotations="enabled">
    <!-- Disable access to all controller methods -->
    <protect-pointcut expression="execution(* com.mycompany.controllers.*Controller.*(..))"
         access="ROLE_THAT_DOES_NOT_EXIST"/>
</global-method-security>
@Controller
@RequestMapping("/test")
public MyController {

    @RequestMapping("")
    public void tryToGetSomething() {
      // pointcut rule -> no one has ROLE_THAT_DOES_NOT_EXIST -> no one can call this code
    }

    @RequestMapping("/public")
    @PreAuthorized("permitAll")
    public void tryToGetSomethingPublic() {
      // annotations take precedence over pointcuts, so anyone can call this code due to @PreAuthorized("permitAll") rule
    }
}

请参阅官方文档中的corresponding entry。也许您可以使用denyAll代替ROLE_THAT_DOES_NOT_EXIST

希望这有帮助。

答案 1 :(得分:0)

我试图实现同样的目标,但问题是方法安全级别适用于通过AOP调用的每个方法。如果您默认拒绝访问,则必须注释几乎所有内容:)

使用基于URL的安全性,您可以按白名单继续:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.anyRequest().denyAll();
}

遗憾的是,显而易见的缺点是每个URL都必须在此处获得授权,从而创建一种依赖性磁体。但是,集中URL路径映射可能是一件好事吗?