2011-10-03 228 views
13

我试图在类型级别上使用@PreAuthorize注释来保护控制器,并尝试通过使用不同的@PreAuthorize注释某些方法来覆盖该行为。然而,问题在于Spring首先评估方法注释(授予访问权限),然后评估类别注释(拒绝访问)。Spring Security的类型级@PreAuthorize不能在方法级别上覆盖

有什么方法可以颠倒这个顺序吗?我还没弄明白。

编辑:

在方法层面上,我要授予访问权限,只非注册用户:

@PreAuthorize("isAnonymous()") 
@RequestMapping(value = "/create", method = RequestMethod.GET) 
public String renderCreateEntity(ModelMap model) { 
    return userService.renderCreateEntity(model); 
} 

然而,对于这个控制器的标准,应该是只允许充分验证的用户:

@Controller 
@RequestMapping(value = "/user") 
@PreAuthorize("isFullyAuthenticated()") 
public class UserController { [...] } 

当调试步进通过应用程序,我看到isAnonymous()首先计算,然后isFullyAuthenticated()从而导致在授予访问权限并立即拒绝访问权限。

+0

您使用的是哪个版本的Spring Security? – beny23

+0

一切春天是3.0.5.RELEASE – chzbrgla

回答

11

感谢您的回复。 但是,答案却完全不同:)

我把这个放在这里以防其他人有同样的问题。

我在@InitBinder带注释的方法中注册了自定义验证程序。此绑定方法在控制器上请求的方法调用后调用。由于此绑定方法未用@PreAuthorize进行注释,请求被拒绝。

的解决方案是诠释这样的装订方法:

@InitBinder 
@PreAuthorize("permitAll") 
public void initBinder(WebDataBinder binder) { 
    binder.setValidator(validator); 
} 

然后,该方法从我的OP评价像预期的要求。

5

问题不在于您需要更改授予和拒绝的顺序。问题很简单,方法级别注释覆盖级别注释。

PrePostAnnotationSecurityMetadataSource Java Doc:

注释可以对类或方法,和具体方法的注解来指定优先。

该逻辑的具体实现在类PrePostAnnotationSecurityMetadataSource的方法findAnnotation中完成。 (不幸的是,这种方法是私人的。)

所以你可以写自己的MethodSecurityMetadataSource,如果你看看代码PrePostAnnotationSecurityMetadataSource,你会看到它是多么容易。

但是最后一个警告:结束:困难的任务不是重写方法,困难的任务是将新的MethodSecurityMetadataSource“注入”到安全系统中。我相信你不能用Spring安全性命名空间配置来完成它,所以你需要通过显式的bean声明来替换spring安全性命名空间。

+0

我其实_WANT_方法级别注释覆盖类级别注释。但是方法级别注释首先被评估,而第二级别是级别级别,因此类级别注释实际上会覆盖方法的注释。我会编辑一些例子到我的问题。 – chzbrgla

+0

从我的测试中,这不再是真的。如果您有类级别和方法级别的安全注释(@Secured或@PreAuthorized),它们都会运行。如果方法级别注释更具限制性,这就好了。如果限制较少,则不起作用。我最终将我的限制较少的方法分解到另一个控制器中。 –

相关问题