我有一个控制器,它有很多操作,它指定了一个默认的类级别的@PreAuthorize注解,但我想让任何人进行的操作之一(“显示”操作)。如何在Spring Security中获取permitAll不会在@Controller对象中抛出AuthenticationCredentialsNotFoundException?
@RequestMapping("/show/{pressReleaseId}")
@PreAuthorize("permitAll")
public ModelAndView show(@PathVariable long pressReleaseId) {
ModelAndView modelAndView = new ModelAndView(view("show"));
modelAndView.addObject("pressRelease",
sysAdminService.findPressRelease(pressReleaseId));
return modelAndView;
}
不幸的是,春季安全抛出此异常:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:321)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:195)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
我怎样才能让Spring Security不会抛出此异常?我只想让任何人进入 - 非认证用户和认证用户 - 每个人。
我唯一的解决方案是把这个方法放到另一个控制器中,完全没有@PreAuthorize ...这将工作,但这是愚蠢的。我想将我所有的新闻发布活动保留在同一控制器中。
感谢您的帮助!
嗯,真的很烂,因为这意味着,而不是指定一个类级别的默认值,我必须指定X相同的@PreAuthorize注释,然后为每个控制器操作进行X测试,以验证我没有忘记包含它的所有除show()动作之外的其他动作。这对春季安全来说只是一个糟糕的设计。他们应该有一个“doNothing”命令,以允许类级别的默认设置正常工作:( – egervari 2010-12-20 07:03:42
由于'@ PreAuthorize'注释的内容是Spring EL表达式,您是否可以编写一个始终返回true的表达式? '@PreAuthorize(“true”)'?我没有尝试过,但它似乎是一个可能的解决方法... – gutch 2010-12-20 07:19:21
这是值得一试;但不,不起作用。哦,好吧......我有这么多控制器存在分裂的安全问题,我认为这对于Spring安全性来说非常混乱,以迫使开发人员分别测试每个动作并且不使用类级别的默认值。我得告诉他们解决这个问题,因为这对于大型应用程序来说很糟糕。 – egervari 2010-12-20 08:41:46