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

SpringBoot 3.1.5升级后PUT/POST接口403 Forbidden问题求助

SpringBoot 3.1.5升级后PUT/POST接口返回403 Forbidden问题

我已将SpringBoot从2.7.17版本升级至3.1.5版本,并按照官方指南更新了安全配置类,期间解决了部分问题,但目前遇到PUT或POST请求的接口返回403 Forbidden的问题。

出现问题的接口

  • POST /app/order/comment
  • PUT /app/order

可正常访问的接口

  • 所有使用GET方法的接口

当前安全配置

@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableConfigurationProperties(AppConfigProperties.class)
@EnableMethodSecurity(prePostEnabled = true)
public class WebappSecurityConfiguration {

    private static final String CUSTOM_CSRF_COOKIE_NAME = "CUSTOM-XSRF-TOKEN";

    @Bean
    @Order(1)
    SecurityFilterChain internalAPISecurityConfig(HttpSecurity http, AppConfigProperties configProps) throws Exception {

        String camundaWebAppUrlPattern = "/camunda/**";

        CookieCsrfTokenRepository csrfRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();

        csrfRepository.setCookieName(CUSTOM_CSRF_COOKIE_NAME);

        http
            .csrf(csrf -> csrf
                    .ignoringRequestMatchers(AntPathRequestMatcher.antMatcher(camundaWebAppUrlPattern))
                    .csrfTokenRepository(csrfRepository)
            )
            .authorizeHttpRequests(authorize -> {
                authorize.requestMatchers(AntPathRequestMatcher.antMatcher(HttpMethod.GET, "/favicon.ico")).permitAll()
                        .requestMatchers(AntPathRequestMatcher.antMatcher(camundaWebAppUrlPattern)).hasRole("ADMIN")
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/app/**")).hasAnyRole("ADMIN", "USER")
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/engine-rest/**")).hasAnyRole("ADMIN", "USER")
                        .requestMatchers(AntPathRequestMatcher.antMatcher("/error")).authenticated()
                        .anyRequest().denyAll();
            })
            .logout(logout -> logout
                .logoutUrl("/app/logout")
                // Redirect URL from config
                .logoutSuccessUrl(configProps.getLogoutUrl())
            );
       
        http.apply(new RequestHeaderAuthenticationConfigurer());

        return http.build();
    }
}

Controller代码

@RestController
@RequestMapping("/app")
public class OrderController {
    @Autowired
    private ProductOrderService productOrderService;

    @Autowired
    private AuditService auditService;

    @PutMapping("/activities")
    @PreAuthorize("!hasRole('ROLE_VISITOR')")
    public CustomResponse activityUpdate(@RequestBody ActivitiesUpdateDto activitiesUpdateDto)
            throws JsonProcessingException {
        return productOrderService.activityUpdate(activitiesUpdateDto);
    }

    @GetMapping("/orders/products")
    public List<OrderDto> getOrders(@RequestParam("search") Optional<String> searchTerm) {
        return productOrderService.fetchOrders(searchTerm.isPresent() ? searchTerm.get() : null);
    }
    
    @PutMapping("/order")
    @PreAuthorize("!hasRole('ROLE_VISITOR')")
    public CustomResponse updateOrder(@RequestBody OrderUpdateDto orderUpdateDto) {
        return productOrderService.updateOrder(orderUpdateDto);
    }

    @PostMapping("/order/comment")
    public CustomerResponse addComment(@RequestBody CommentDto commenteDto) {
        return productOrderService.addComment(commenteDto);
    }
}

请求Cookie信息

所有接口请求都会发送包含以下内容的Cookie请求头:

Cookie: Idea-56ec4e87=6d30aeb7-9c46-4d74-be5b-18c896652a0c; CUSTOM-XSRF-TOKEN=527851d7-ac94-424a-b55f-bf7b6a1c1d6c; JSESSIONID=9A9C968680E61F50CD936B6C7199F631

升级前的安全配置

SecurityFilterChain internalAPISecurityConfig(HttpSecurity http, AppConfigProperties configProps)
        throws Exception {

    String camundaWebAppUrlPattern = "/camunda/**";

    String[] staticRessourceUrlPatterns = new String[] { "/favicon.ico" };

    CookieCsrfTokenRepository csrfRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
    csrfRepository.setCookieName(CUSTOM_CSRF_COOKIE_NAME);

    http
        .csrf(csrf -> csrf
                .ignoringAntMatchers(camundaWebAppUrlPattern)
                .csrfTokenRepository(csrfRepository)
        )
        .authorizeHttpRequests(authorize -> authorize
           .antMatchers(HttpMethod.GET, staticRessourceUrlPatterns).permitAll()
            .antMatchers(camundaWebAppUrlPattern).hasRole("ADMIN")
            .antMatchers("/app/**", "/engine-rest/**").hasAnyRole("ADMIN", "USER")
            .antMatchers("/error").authenticated()
            .anyRequest().denyAll()
        )
        .logout(logout -> logout
            .logoutUrl("/app/logout")
            .logoutSuccessUrl(configProps.getLogoutUrl())
        );
    http.apply(new RequestHeaderAuthenticationConfigurer());

    return http.build();
}

已尝试的解决方法

  • 使用csrf.disable()关闭CSRF防护,此时所有接口均可访问,但不符合客户需求,需保持CSRF开启状态。
  • 移除POST方法addComment上的@PreAuthorize("!hasRole('ROLE_VISITOR')")注解,仍返回403错误。
  • 将@PreAuthorize("!hasRole('ROLE_VISITOR')")修改为@PreAuthorize("hasRole('USER') or hasRole('ADMIN')"),甚至尝试去掉ROLE_前缀,问题依旧。

恳请各位提供解决思路或方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 21:37:15