目前,我试图弄清楚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
}
}
这种方法的主要原因是:安全性;-)
。在编写代码时总是可以忘记一些注释。使用这种方法,这样的错误不会影响敏感数据的安全性。
所以我的问题是:我怎样才能做到这一点?
答案 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路径映射可能是一件好事吗?