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

Spring Security返回401而非403问题排查(Spring Boot3+Security6)

问题分析与解决方案

你的配置存在两个关键问题,导致POST请求出现异常:

1. CSRF保护拦截了POST请求(核心原因)

Spring Security 6默认开启CSRF保护机制,该机制会拦截所有未携带CSRF令牌的POST请求,直接返回401未授权——这就是USER和ADMIN角色都无法正常访问POST接口的原因。而GET请求不受CSRF保护影响,所以你的GET规则能正常运行。

解决办法:

  • 如果是API场景(比如用Postman、curl测试接口),可以直接关闭CSRF保护:
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                .csrf(csrf -> csrf.disable()) // 关闭CSRF保护
                .authorizeHttpRequests(requests -> {
                    requests.requestMatchers("/", "/login").permitAll();
                    requests.requestMatchers(HttpMethod.POST).hasRole("ADMIN");
                    requests.requestMatchers(HttpMethod.GET).hasAnyRole("USER", "ADMIN");
                    requests.anyRequest().authenticated();
                })
                .httpBasic(Customizer.withDefaults())
                .formLogin(form -> form
                        .loginPage("/login")
                        .permitAll());
    
            return http.build();
    }
    
  • 如果是浏览器表单提交场景,需要在表单中添加CSRF令牌,比如使用Thymeleaf时可以添加:
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
    

2. 角色前缀匹配问题(潜在隐患)

Spring Security的hasRole()方法会自动给角色名添加ROLE_前缀,比如hasRole("ADMIN")实际匹配的是权限为ROLE_ADMIN的用户。如果你的用户权限存储的是ADMIN而非ROLE_ADMIN,即使解决了CSRF问题,ADMIN角色用户也会返回403禁止访问。

解决办法:

  • 要么将用户的权限设置为ROLE_ADMIN(推荐,符合Spring Security默认规范)
  • 要么改用hasAuthority()方法,该方法不会自动添加前缀:
    requests.requestMatchers(HttpMethod.POST).hasAuthority("ADMIN");
    requests.requestMatchers(HttpMethod.GET).hasAnyAuthority("USER", "ADMIN");
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:32:51