在 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-id
client-secret: your-github-client-secret
scope: user:email, read:user # 请求的用户权限范围
三、Spring Security 核心配置
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public 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();
}
@Autowired
private 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 {
@Override
public 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-id
client-secret: github-secret
google:
client-id: google-client-id
client-secret: google-secret
scope: 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 授权页面,完成授权后返回应用并访问受保护资源。