Spring Security,Method Security annotation(@Secured)无效(java config)

sil*_*awk 17 java security spring spring-security spring-boot

我正在尝试使用@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);
    }

.....

}
Run Code Online (Sandbox Code Playgroud)

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

@RestController
@RequestMapping("/api/groups")
public class GroupController {

    @Autowired
    private GroupService groupService;

    @Secured("ADMIN")
    @RequestMapping
    public List<Group> list() {
        return groupService.findAll();
    }

}
Run Code Online (Sandbox Code Playgroud)

通过网址限制访问是有效的,具有:

.antMatchers("/api/**").hasAuthority("ADMIN")
Run Code Online (Sandbox Code Playgroud)

也许我忘了指定我想要按角色限制?

UPD: 根据规则,在哪一层必须@PreAuthorize("hasRole('ADMIN')")在Controller层或Service层中?

Mud*_*sar 33

请加上这个

@EnableGlobalMethodSecurity(securedEnabled = true)
Run Code Online (Sandbox Code Playgroud)

此元素用于在应用程序中启用基于注释的安全性(通过在元素上设置适当的属性),还可以将安全性切入点声明组合在一起,这些声明将专门用于整个应用程序上下文@Secured.因此,您的代码应如下所示

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{..
Run Code Online (Sandbox Code Playgroud)


Ser*_*sta 13

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

首先是因为在Spring Security手册中从未引用它作为例子......开玩笑但是将Spring工具放在他们不想去的地方可能会很棘手.

更严重的是,您应该启用@Mudassar已经说过的方法安全性.手册说:

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

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MethodSecurityConfig {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

我试图遵循的规则是:

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

  • 只使用 HTTP 安全性的缺点是,通常 URL 是通过使用与请求相关的注释(例如“@GetMapping”、“@POST”等)在控制器中定义的。但是,URL 到角色的映射被放置在单独的 HTTP 安全配置类中。一旦控制器中的 URL 发生更改,它实际上就会失去其当前的角色要求,除非您也更改安全配置中的 URL。如果方法被注释,它们就不会意外丢失角色信息。 (2认同)

use*_*708 11

我知道这个帖子很老了,我的答案暗示了这个帖子中不同人的部分答案; 但这里列出了陷阱和答案的列表:

  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 { ... 
    }
Run Code Online (Sandbox Code Playgroud)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
open class WebSecurityConfig : WebSecurityConfigurerAdapter() {
Run Code Online (Sandbox Code Playgroud)

问候


sil*_*awk 7

这个问题解决了。

我加 @EnableGlobalMethodSecurity(prePostEnabled = true)

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter{
}
Run Code Online (Sandbox Code Playgroud)

而在控制器我改变@Secured("ADMIN")@PreAuthorize("hasRole('ADMIN')")

  • @Secured("ROLE_ADMIN") 应该同样与 `@EnableGlobalMethodSecurity` 注释中设置的 `securedEnabled=true` 标志一起使用,按照 @user1210708 的答案。 (2认同)