You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security 6.1.3中@PreAuthorize注解失效问题求助

问题:Spring Security @PreAuthorize权限控制失效

在Spring 3.1.3搭配Spring Security 6.1.3环境下,使用@PreAuthorize注解时出现权限控制失效问题。预期配置:

  • /rest/api/security/hello:公开访问
  • /rest/api/security/boolean:仅允许ROLE_USER访问
  • /rest/api/security/number:仅允许ROLE_ADMIN访问

当前现象:私有接口可正常跳转至登录页,但两种角色(USER/ADMIN)均能访问两个私有接口,@PreAuthorize校验未生效。调用接口时已确认用户权限正确(USER角色显示[ROLE_USER],ADMIN角色显示[ROLE_ADMIN])。

Controller代码

@RestController
@RequestMapping(value = "/rest/api/security")
public class BaseController extends HateosController{
    
    @GetMapping("/hello")
    public final String getHello() {
        return "Ciao!";
    }
    
    @GetMapping("/boolean")
    @PreAuthorize("hasRole('ROLE_USER')")
    public final boolean getBoolean(Authentication authentication) {
        System.out.println("User Authorities: " + authentication.getAuthorities());
        return true;
    }
    
    @GetMapping("/number")
    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    public final Integer getNumber(Authentication authentication) {
        System.out.println("User Authorities: " + authentication.getAuthorities());
        return 115683;
    }
}

SecurityConfig代码

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
    
    @Bean
    public UserDetailsService userDetailsService(PasswordEncoder encoder) {
        UserDetails admin = User.withUsername("admin").password(encoder.encode("admin")).roles("ADMIN").build();
        UserDetails user = User.withUsername("user").password(encoder.encode("user")).roles("USER").build();
        return new InMemoryUserDetailsManager(admin, user);
    }
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.csrf().disable()
                .authorizeHttpRequests()
                .requestMatchers("/rest/api/security/hello").permitAll().anyRequest().authenticated().and().formLogin()
                .and().build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

解决建议

  • 开启prePostEnabled配置:Spring Security 6.x中@EnableMethodSecurity默认禁用pre-post注解支持,需显式开启,修改注解为:

    @EnableMethodSecurity(prePostEnabled = true)
    

    @PreAuthorize属于pre-post注解范畴,必须开启此配置才能触发校验。

  • 修正权限表达式写法:

    • hasRole方法会自动为角色添加ROLE_前缀,因此/boolean接口的注解应改为:
      @PreAuthorize("hasRole('USER')")
      
      原写法hasRole('ROLE_USER')会实际校验ROLE_ROLE_USER,与用户权限不匹配。
    • /number接口的hasAuthority('ROLE_ADMIN')写法正确,因为roles("ADMIN")构建用户时会自动添加ROLE_前缀,用户权限为ROLE_ADMIN,与表达式匹配。
  • 修复版本兼容性问题:Spring Security 6.x要求依赖Spring Framework 6.0及以上版本,而当前使用的Spring 3.1.3版本过低,存在严重兼容性问题,这很可能是权限校验失效的根本原因。请升级Spring Framework至6.0+版本,确保与Spring Security 6.1.3版本匹配。

内容的提问来源于stack exchange,提问作者Luca Ferretti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:05:30