求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,改用SecurityFilterChainBean配置,旧代码直接迁移会导致权限规则不生效; - CSRF配置默认更严格,旧版本未设置
CookieCsrfTokenRepository.withHttpOnlyFalse(),导致前端无法获取CSRF令牌,POST请求因缺少令牌被拦截。
内容的提问来源于stack exchange,提问作者alikian
相关产品推荐
相关产品推荐

