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

Spring Boot 3.1.0中Spring Security禁止POST请求的问题排查

Spring Boot 3.1.0集成Spring Security时POST请求403问题

环境配置

插件配置

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.1.0'
    id 'io.spring.dependency-management' version '1.1.0'
}

依赖配置

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-security'

测试端点代码

@Slf4j
@RestController
@RequestMapping("/open")
public class OpenedController {

    @GetMapping
    public String secureHi() {
        log.info("Hi, I am opened.");
        return "Hi, I am opened.";
    }

    @PostMapping
    public String secureHPost(@RequestBody MyUser myUser) {
        log.info("Hi, I am opened POST. myUser ={}", myUser);
        return "Hi, I am opened POST.";
    }
}

安全配置类

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {

    UserDetails admin = User.withUsername("chitta")
            .password(passwordEncoder.encode("chitta"))
            .roles("ADMIN")
            .build();

    UserDetails user = User.withUsername("aaa")
            .password(passwordEncoder.encode("aa"))
            .roles("USER")
            .build();
    return new InMemoryUserDetailsManager(admin, user);
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http.authorizeHttpRequests(
            (authorize) -> authorize
                    .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
                    .requestMatchers("/open**").permitAll()
                    .anyRequest().denyAll()
    );

    return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {

    return new BCryptPasswordEncoder();
}
}

问题现象

访问GET /open正常,但访问POST /open返回403 Forbidden:

{
"timestamp": "2023-06-16T08:50:43.240+00:00",
"status": 403,
"error": "Forbidden",
"path": "/open"
}

尝试过.requestMatchers(HttpMethod.POST, "/open**").permitAll(),问题依旧。


解决方案

问题根源是Spring Security默认开启了CSRF防护,对于POST、PUT等非安全HTTP方法,会强制验证CSRF令牌,而你的请求未携带该令牌,因此被拦截返回403。

有两种处理方案:

  1. 关闭CSRF保护(适合无状态REST API场景):
    在securityFilterChain配置中添加关闭CSRF的代码,修改后的配置如下:

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    
        http.csrf(csrf -> csrf.disable()) // 关闭CSRF防护
            .authorizeHttpRequests(
                (authorize) -> authorize
                        .dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
                        .requestMatchers("/open**").permitAll()
                        .anyRequest().denyAll()
        );
    
        return http.build();
    }
    
  2. 携带CSRF令牌(适合有状态Web应用场景):

    • 浏览器端:可通过访问/_csrf端点获取令牌,在请求头中添加X-CSRF-TOKEN字段携带令牌;
    • API客户端:在请求头中直接添加X-CSRF-TOKEN字段,值为预先获取的令牌。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:32:32