持有有效JSESSIONID仍触发Error 403(Spring Boot OAuth2场景)
问题解决:OAuth2登录后POST请求返回403
原因分析
Spring Security默认开启了CSRF(跨站请求伪造)防护,对于POST、PUT、DELETE等非GET请求,要求请求中携带有效的CSRF令牌。你提交的表单没有包含CSRF令牌,所以被安全拦截器拒绝,返回403错误。
解决方案
方案1:在表单中添加CSRF令牌(推荐)
利用Thymeleaf自动集成的Spring Security支持,在表单内添加CSRF令牌字段即可:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
修改后的完整表单代码:
<form method="post" action="/api/adddrink"> <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" /> <div class="input-group mb-3"> <button type="submit" data-th-value="${cocktailDetails.idDrink}" name="idDrink">Add to Profile</button> </div> </form>
方案2:关闭CSRF防护(仅测试环境使用)
如果是测试场景临时需要,可以自定义Spring Security配置类关闭CSRF,但生产环境绝对不建议这么做,会带来安全风险:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .oauth2Login() // 保留原有OAuth2登录配置 .and() .csrf().disable(); // 关闭CSRF防护 return http.build(); } }
补充说明
- GET请求正常是因为Spring Security默认不对GET请求做CSRF校验,这是为了兼容静态资源访问等场景。
- 即使JSESSIONID存在,没有CSRF令牌的POST请求依然会被拦截,这是CSRF防护的核心逻辑——通过令牌验证请求的合法性。
内容的提问来源于stack exchange,提问作者justsayKK
相关产品推荐
相关产品推荐

