在 Spring Security 中集成 GitHub 的 OAuth 2.0 登录,可以实现用户通过 GitHub 账号快速认证。以下是完整的分步实现指南和代码示例:
一、前置准备
1. 在 GitHub 注册 OAuth 应用
- 访问 GitHub Settings → Developer settings → OAuth Apps
- 点击 New OAuth App,填写:
• Application name: 你的应用名称
• Homepage URL:http://localhost:8080
(开发环境)
• Authorization callback URL:http://localhost:8080/login/oauth2/code/github
- 生成 Client ID 和 Client Secret
二、Spring Boot 项目配置
1. 添加依赖
<!-- Spring Security OAuth2 Client -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
2. 配置 application.yml
spring:security:oauth2:client:registration:github:client-id: your-github-client-idclient-secret: your-github-client-secretscope: user:email, read:user # 请求的用户权限范围
三、Spring Security 核心配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorize -> authorize.antMatchers("/", "/login**", "/error**").permitAll().anyRequest().authenticated()).oauth2Login(oauth2 -> oauth2.loginPage("/login") // 自定义登录页.userInfoEndpoint(userInfo -> userInfo.userService(customOAuth2UserService) // 自定义用户处理).successHandler(loginSuccessHandler()) // 登录成功处理.failureHandler(loginFailureHandler()) // 登录失败处理).logout(logout -> logout.logoutSuccessUrl("/").permitAll());return http.build();}@Autowiredprivate CustomOAuth2UserService customOAuth2UserService;// 登录成功处理器private AuthenticationSuccessHandler loginSuccessHandler() {return (request, response, authentication) -> {response.sendRedirect("/dashboard");};}// 登录失败处理器private AuthenticationFailureHandler loginFailureHandler() {return (request, response, exception) -> {response.sendRedirect("/login?error=true");};}
}
四、自定义用户信息处理
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {@Overridepublic OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {OAuth2User oauth2User = super.loadUser(userRequest);// 提取 GitHub 用户信息String username = oauth2User.getAttribute("login");String email = getEmailFromAttributes(oauth2User.getAttributes());String name = oauth2User.getAttribute("name");// 构建应用内用户模型(可在此处保存用户到数据库)return new DefaultOAuth2User(Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")),oauth2User.getAttributes(),"id" // 对应 GitHub 用户信息的唯一标识字段名);}// 获取用户邮箱(需申请 user:email 权限)private String getEmailFromAttributes(Map<String, Object> attributes) {List<Map<String, Object>> emails = (List<Map<String, Object>>) attributes.get("email");if (emails != null && !emails.isEmpty()) {return (String) emails.get(0).get("email");}return null;}
}
五、控制器示例
@Controller
public class LoginController {@GetMapping("/dashboard")public String dashboard(Model model, @AuthenticationPrincipal OAuth2User user) {model.addAttribute("username", user.getAttribute("login"));return "dashboard";}@GetMapping("/login")public String loginPage() {return "login";}
}
六、前端页面示例
1. login.html
(Thymeleaf 模板)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Login</title>
</head>
<body><h2>选择登录方式</h2><a th:href="@{/oauth2/authorization/github}"><button>使用 GitHub 登录</button></a><div th:if="${param.error}" style="color: red">登录失败,请重试!</div>
</body>
</html>
2. dashboard.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Dashboard</title>
</head>
<body><h2>欢迎, <span th:text="${username}"></span>!</h2><a href="/logout">退出登录</a>
</body>
</html>
七、高级配置
1. 同时支持多个 OAuth 提供商(如 Google + GitHub)
spring:security:oauth2:client:registration:github:client-id: github-client-idclient-secret: github-secretgoogle:client-id: google-client-idclient-secret: google-secretscope: email, profile
2. 自定义授权端点路径
.oauth2Login(oauth2 -> oauth2.authorizationEndpoint(authorization -> authorization.baseUri("/oauth2/authorize") // 默认是 /oauth2/authorization/{providerId})
)
八、生产环境注意事项
- HTTPS 强制启用
http.requiresChannel().anyRequest().requiresSecure();
- 加密敏感信息
• 将client-secret
存储在环境变量或 Vault 中client-secret: ${GITHUB_CLIENT_SECRET}
- 优化用户信息存储
// 在 CustomOAuth2UserService 中将用户保存到数据库 User user = userRepository.findByGithubId(githubId).orElseGet(() -> userRepository.save(new User(githubId, email)));
九、常见问题排查
1. 重定向 URI 不匹配
• 检查 GitHub OAuth App 的 Authorization callback URL 是否与 application.yml
中的配置一致
2. 权限不足
• 确保申请的 scope
正确(如需要用户邮箱需添加 user:email
)
3. CSRF 错误
• 确保登录表单包含 CSRF Token(Spring Security 默认启用)
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
通过以上配置,您的 Spring Boot 应用即可实现基于 GitHub 的 OAuth 2.0 登录。用户点击 GitHub 登录按钮后,将跳转至 GitHub 授权页面,完成授权后返回应用并访问受保护资源。