4

我有一个控制器,它有很多操作,它指定了一个默认的类级别的@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 ...这将工作,但这是愚蠢的。我想将我所有的新闻发布活动保留在同一控制器中。

感谢您的帮助!

回答

3

允许任何人访问控制器方法的正常方法是而不是使用任何Spring Security注释对其进行注释;即没有@PreAuthorize没有@Secured

你应该能够简单地从show()方法去除@PreAuthorize,任何留在该控制器的其他方法的注释。无论您如何使用show()方法,其他方法都将保持安全。

+0

嗯,真的很烂,因为这意味着,而不是指定一个类级别的默认值,我必须指定X相同的@PreAuthorize注释,然后为每个控制器操作进行X测试,以验证我没有忘记包含它的所有除show()动作之外的其他动作。这对春季安全来说只是一个糟糕的设计。他们应该有一个“doNothing”命令,以允许类级别的默认设置正常工作:( – egervari 2010-12-20 07:03:42

+0

由于'@ PreAuthorize'注释的内容是Spring EL表达式,您是否可以编写一个始终返回true的表达式? '@PreAuthorize(“true”)'?我没有尝试过,但它似乎是一个可能的解决方法... – gutch 2010-12-20 07:19:21

+1

这是值得一试;但不,不起作用。哦,好吧......我有这么多控制器存在分裂的安全问题,我认为这对于Spring安全性来说非常混乱,以迫使开发人员分别测试每个动作并且不使用类级别的默认值。我得告诉他们解决这个问题,因为这对于大型应用程序来说很糟糕。 – egervari 2010-12-20 08:41:46

7

我想你没有启用anonymouse认证过滤器。

如果您使用命名空间配置和auto-config = "true",则应默认启用它。如果您不使用自动配置,则可以启用匿名过滤器为<security:anonymous />

+0

这应该是被接受的答案。奇迹般有效! – 2013-11-28 17:11:40

+0

这是最好的答案 - 请参阅此处http://docs.spring.io/spring-security/site/docs/current/reference/html/anonymous.html – kboom 2017-08-21 16:03:16

3

默认情况下,弹簧安全插件的更新版本(版本2)更改。这意味着所有的控制器默认都是安全的(您需要登录才能看到它们)。删除@Secured根本不起作用,它仍然会保持安全。您可以更改此默认行为,但对我而言,新的默认行为是有意义的,因为它更安全。安全性非常重要。

我只用

@Secured(['permitAll']) 

我的控制器,但它也应该适用的方法。

+0

这是无效的Java,请尝试'@Secured(“ permitAll“)' – 2017-07-19 14:22:17

相关问题