Spring Security,Method Security注解(@Secured)不工作(java config)

我正在尝试使用@Secured(“ADMIN”)(没有任何XML,只有java配置,Spring Boot)来设置方法安全注释。 但通过角色访问不起作用。

安全配置:

@Configuration @EnableWebSecurity public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{ ..... @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/api/**").fullyAuthenticated().and() .addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } ..... } 

我想限制访问控制器的方法:

 @RestController @RequestMapping("/api/groups") public class GroupController { @Autowired private GroupService groupService; @Secured("ADMIN") @RequestMapping public List<Group> list() { return groupService.findAll(); } } 

通过url限制访问正在工作,与:

 .antMatchers("/api/**").hasAuthority("ADMIN") 

也许我忘了指定,我想限制的角色?

UPD:按照规则,在控制层或服务层中的哪个层必须是@PreAuthorize("hasRole('ADMIN')")

控制器上的哪种方法安全性不起作用可能有很多原因。

首先,因为它从来没有被引用作为例子在春季安全手册…开玩笑,但它可能是棘手的春季工具,他们不想去。

更严重的是,你应该像@Mudassar所说的那样启用方法安全性。 手册说:

我们可以在任何@Configuration实例上使用@EnableGlobalMethodSecurity批注来启用基于批注的安全性。 例如,以下将启用Spring Security的@Secured注释。

 @Configuration @EnableGlobalMethodSecurity(securedEnabled = true) public class MethodSecurityConfig { // ... } 

请注意,Mudassar的答案是正确的,直到这里。

但方法安全性是基于AOP的,默认情况下在接口上使用JDK代理。 这就是所有示例在服务层上应用方法安全性的原因,因为服务类通常作为接口注入到控制器中。

你当然可以在控制器层上使用它,但是:

  • 要么你所有的控制器都为你实现了所有@Secured注解方法的接口
  • 或者你必须切换到类代理

我试图遵循的规则是:

  • 如果我想保护一个URL,我坚持HTTPSecurity
  • 如果我需要允许更细粒度的访问,我在服务层添加安全性

请加上这个

 @EnableGlobalMethodSecurity(securedEnabled = true) 

此元素用于在应用程序中启用基于注释的安全性(通过在元素上设置适当的属性),并将安全性切入点声明分组在一起,这些声明将被专门用于@Secured整个应用程序上下文中。 因此,你的代码应该是这样的

 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{.. 

我知道这个线程是相当古老的,我的回答暗示着这个线程中各个人的部分答案。 但是这里列出了一个缺陷和答案的清单:

  1. 使用@Secured时,角色名称是(例如)ADMIN; 这意味着@Secured(“ROLE_ADMIN”)的注释。
  2. WebSecurityConfigurerAdapter必须具有@EnableGlobalMethodSecurity(securedEnabled = true)
  3. 和大多数Spring相关的代理一样,确保类和安全方法不是最终的。 对于Kotlin来说,这意味着“开放”每一种方法以及课堂。
  4. 当类及其方法是虚拟的(“打开”)时,则不需要接口。

这是Kotlin工作的一部分:

 @RestController @RequestMapping("api/v1") open class DiagnosticsController { @Autowired lateinit var systemDao : SystemDao @RequestMapping("ping", method = arrayOf(RequestMethod.GET)) @Secured("ROLE_ADMIN") open fun ping(request : HttpServletRequest, response: HttpServletResponse) : String { ... } 

 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) open class WebSecurityConfig : WebSecurityConfigurerAdapter() { 

问候

也许你应该注册你的AppSecurityConfiguration与WebMvcConfig(扩展了WebMvcConfigurerAdapter)相同的上下文。

 AnnotationConfigWebApplicationContext mvcContext = new AnnotationConfigWebApplicationContext(); mvcContext.register(WebMvcConfig.class, SecurityConfig.class); 

您需要使用@secured(ROLE_ADMIN)而不是@secured(ADMIN)。 您需要在角色名称的前面写上“ROLE_” 。 请找到下面提到的例子,确保只有具有Admin角色的用户才能访问list()方法。

 @RestController @RequestMapping("/api/groups") public class GroupController { @Autowired private GroupService groupService; @Secured("ROLE_ADMIN") @RequestMapping public List<Group> list() { return groupService.findAll(); } } 

这个问题解决了。

我添加@EnableGlobalMethodSecurity(prePostEnabled = true)

 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{ } 

在控制器中,我将@Secured("ADMIN")更改为@PreAuthorize("hasRole('ADMIN')")