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

求Spring Boot 3.1.1(Spring Security 6.1.1)OAuth2完整示例

Spring Boot 3.1.1 OAuth2 完整实现示例(含POST 403问题解决)

1. 依赖配置(Maven)

<dependencies>
    <!-- Spring Boot Web 核心依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- OAuth2 客户端依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    <!-- Thymeleaf(可选,用于前端页面渲染) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

2. 应用配置(application.yml)

以Github OAuth2为例,可替换为Google、Gitee等平台的配置:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: 你的平台ClientID
            client-secret: 你的平台ClientSecret
            scope: read:user,user:email
        provider:
          github:
            authorization-uri: https://github.com/login/oauth/authorize
            token-uri: https://github.com/login/oauth/access_token
            user-info-uri: https://api.github.com/user
            user-name-attribute: login
server:
  port: 8080

3. Security 核心配置类

这是解决POST 403问题的关键,适配Spring Security 6的新API:

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;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 授权规则:放行首页、登录相关路径,其他请求需认证
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/login/**", "/error").permitAll()
                .anyRequest().authenticated()
            )
            // OAuth2 登录配置
            .oauth2Login(oauth2 -> oauth2
                .defaultSuccessUrl("/home", true) // 登录成功后跳转首页
            )
            // 退出登录配置
            .logout(logout -> logout
                .logoutSuccessUrl("/")
                .invalidateHttpSession(true)
                .clearAuthentication(true)
            )
            // 解决POST 403:配置CSRF令牌存储,允许前端读取令牌
            .csrf(csrf -> csrf
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            );
        return http.build();
    }
}

4. 控制器示例

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {

    @GetMapping("/")
    public String index() {
        return "index";
    }

    @GetMapping("/home")
    public String home(@AuthenticationPrincipal OAuth2User oAuth2User, Model model) {
        model.addAttribute("userName", oAuth2User.getAttribute("login"));
        model.addAttribute("email", oAuth2User.getAttribute("email"));
        return "home";
    }

    // 测试POST请求接口
    @PostMapping("/api/test")
    @ResponseBody
    public String testPost() {
        return "POST请求执行成功";
    }
}

5. 前端页面示例(index.html,Thymeleaf)

自动携带CSRF令牌,避免POST 403:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>OAuth2 登录演示</title>
    <!-- Thymeleaf自动注入CSRF令牌元数据 -->
    <meta name="_csrf" th:content="${_csrf.token}"/>
    <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>
<body>
    <h1>OAuth2 登录演示</h1>
    <a href="/oauth2/authorization/github">使用Github登录</a>

    <!-- 表单提交POST请求,自动携带CSRF令牌 -->
    <form method="post" action="/api/test">
        <button type="submit">发送POST请求</button>
    </form>

    <!-- AJAX POST请求示例,手动携带CSRF令牌 -->
    <button onclick="sendAjaxPost()">AJAX发送POST</button>
    <script>
        function sendAjaxPost() {
            const csrfToken = document.querySelector('meta[name="_csrf"]').content;
            const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;
            fetch('/api/test', {
                method: 'POST',
                headers: {
                    [csrfHeader]: csrfToken
                }
            }).then(res => res.text()).then(data => alert(data));
        }
    </script>
</body>
</html>

关键说明

Spring Security 5的实现方式导致POST 403的核心原因:

  • Spring Security 6弃用了WebSecurityConfigurerAdapter,改用SecurityFilterChain Bean配置,旧代码直接迁移会导致权限规则不生效;
  • CSRF配置默认更严格,旧版本未设置CookieCsrfTokenRepository.withHttpOnlyFalse(),导致前端无法获取CSRF令牌,POST请求因缺少令牌被拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:41:21