我有一个控制器,它有很多动作,它指定了一个默认的类级别@PreAuthorize注释,但我想让任何人进入其中一个动作(“show”动作)。
@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;
}
不幸的是,Spring Security引发了这个异常:
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 ...这会起作用,但那是愚蠢的。我想在同一个控制器中保留我的所有新闻稿动作。
感谢您的帮助!
答案 0 :(得分:10)
我猜您没有启用匿名身份验证过滤器。
如果使用命名空间配置和auto-config = "true"
,则默认情况下应启用它。如果您不使用自动配置,则可以将匿名过滤器设置为<security:anonymous />
。
答案 1 :(得分:3)
允许任何人访问控制器方法的常规方法是不使用任何Spring Security注释对其进行注释;即没有@PreAuthorize
没有@Secured
等。
您应该能够从@PreAuthorize
方法中删除show()
,任何将注释留在该控制器中的其他方法上。无论您使用show()
方法做什么,其他方法都将保持安全。
答案 2 :(得分:3)
默认情况下,spring安全插件的更新版本(版本2)已更改。这意味着默认情况下所有控制器都是安全的(您需要登录才能看到它们)。删除@Secured根本不起作用,它仍将保持安全。您可以更改此默认行为,但对我来说,新的默认行为是有意义的,因为它更安全。安全性非常重要。
我只使用
@Secured(['permitAll'])
对于我的控制器,但它也适用于方法。