程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Python 基础

    • Python基础
  • Python 进阶

    • 装饰器与生成器
    • 异常处理
    • 标准库精讲
    • 模块与包
    • pip包管理工具
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
前端 (opens new window)
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • SpringSecurity

    • Spring Security是什么
    • 认证与授权的基本概念
    • Spring Security 的默认配置
    • SpringSecurity的默认登录页
    • Spring Security 的 Filter 机制
    • HttpSecurity 与自定义登录页面
    • Spring Security 的核心组件与扩展
    • Spring Security 中的用户认证与角色管理
    • Spring Security 的授权机制与安全表达式
    • Security 的 Session 与 Token 管理
    • Spring Security 集成第三方登录
      • 1. OAuth2 基础概念
      • 2. Spring Security OAuth2 Client 集成 GitHub 登录
      • 3. Spring Security OAuth2 Client 集成 Gitee 登录
      • 4. 定义用户实体类并保存到数据库
      • 5. 自定义 OAuth2 登录逻辑并保存用户信息
      • 6. OAuth2 登录的完整流程
    • Spring Security 集成 QQ 登录与 JWT 认证
    • Spring Security 登录认证源码
    • Spring Security - JWT认证实战
    • Spring Security - JWT授权实战
    • Spring Security 异常处理与自定义逻辑
  • SpringSecurity
  • SpringSecurity
scholar
2024-08-20
目录

Spring Security 集成第三方登录

# Spring Security 集成第三方登录

# 1. OAuth2 基础概念

OAuth2 主要有四种授权模式:

  1. 授权码模式(Authorization Code):常用于 Web 应用程序,安全性高。
  2. 简化模式(Implicit):用于无后台的前端应用,Token 直接通过 URL 传递。
  3. 密码模式(Resource Owner Password Credentials):用户直接提供用户名和密码,适用于高信任场景。
  4. 客户端模式(Client Credentials):应用程序间的授权,适用于无用户参与的场景。

在第三方登录集成中,授权码模式是最常用且推荐的模式。

# 2. Spring Security OAuth2 Client 集成 GitHub 登录

首先,在项目中引入相关依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
1
2
3
4

GitHub 登录配置(application.yml):

spring:
  security:
    oauth2:
      client:
        registration:
          github:  # 配置 GitHub 登录
            client-id: your-github-client-id  # 从 GitHub 开发者控制台获取,必须配置
            client-secret: your-github-client-secret  # 从 GitHub 开发者控制台获取,必须配置
            scope: read:user,repo  # 请求的权限范围,可根据需求调整
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"  # Spring Security 自动处理回调,保持默认即可
            client-name: GitHub  # 客户端名称,配置成任意可识别的名称
        provider:
          github:
            authorization-uri: https://github.com/login/oauth/authorize  # GitHub 授权页面的 URL
            token-uri: https://github.com/login/oauth/access_token  # 获取访问 Token 的 URL
            user-info-uri: https://api.github.com/user  # 获取用户信息的 URL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

代码解析:

  • client-id 和 client-secret:是应用的标识和密钥,必须从 GitHub 开发者控制台获取。
  • redirect-uri:授权成功后的回调地址,Spring Security 会自动处理,无需手动配置。
  • scope:指定应用请求的权限范围,如读取用户信息、仓库等。

# 3. Spring Security OAuth2 Client 集成 Gitee 登录

Gitee 的配置类似于 GitHub,只需更改部分配置参数。

Gitee 登录配置(application.yml):

spring:
  security:
    oauth2:
      client:
        registration:
          gitee:  # 配置 Gitee 登录
            client-id: your-gitee-client-id  # 从 Gitee 开发者平台获取,必须配置
            client-secret: your-gitee-client-secret  # 从 Gitee 开发者平台获取,必须配置
            scope: user_info  # Gitee 请求的权限范围,通常为获取用户信息
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"  # Spring Security 自动处理回调,保持默认即可
            client-name: Gitee  # 客户端名称,可自定义
        provider:
          gitee:
            authorization-uri: https://gitee.com/oauth/authorize  # Gitee 授权页面的 URL
            token-uri: https://gitee.com/oauth/token  # 获取访问 Token 的 URL
            user-info-uri: https://gitee.com/api/v5/user  # 获取用户信息的 URL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

配置要点:

  • authorization-uri 和 token-uri:分别是 Gitee 的授权地址和 Token 获取地址,必须正确配置。
  • user-info-uri:用于获取 Gitee 用户的详细信息。

# 4. 定义用户实体类并保存到数据库

为了将获取的用户信息保存到数据库中,我们需要创建一个实体类,并使用 JPA 或 MyBatis 进行持久化操作。

用户实体类示例(User.java):

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;  // 用户在数据库中的唯一标识

    private String username;  // 用户名
    private String email;  // 用户邮箱
    private String avatarUrl;  // 用户头像 URL
    private String provider;  // 第三方平台名称,如 "github" 或 "gitee"
    private String providerId;  // 第三方平台的用户ID

    // 省略 Getter 和 Setter 方法

    // 构造函数
    public User() {}

    public User(String username, String email, String avatarUrl, String provider, String providerId) {
        this.username = username;
        this.email = email;
        this.avatarUrl = avatarUrl;
        this.provider = provider;
        this.providerId = providerId;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

持久化接口(使用 Spring Data JPA):

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByProviderAndProviderId(String provider, String providerId);
}
1
2
3
4
5

# 5. 自定义 OAuth2 登录逻辑并保存用户信息

我们可以自定义 OAuth2UserService 来实现用户信息的获取和保存。

自定义用户服务(实现 OAuth2UserService 接口):

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {

    @Autowired
    private UserRepository userRepository;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) {
        OAuth2User oauth2User = new DefaultOAuth2UserService().loadUser(userRequest);

        // 获取第三方平台的用户信息
        String provider = userRequest.getClientRegistration().getRegistrationId();  // 如 "github" 或 "gitee"
        String providerId = oauth2User.getName();  // 第三方平台的用户ID
        String username = oauth2User.getAttribute("login");  // 用户名(取决于具体平台,GitHub 为 "login")
        String email = oauth2User.getAttribute("email");  // 邮箱
        String avatarUrl = oauth2User.getAttribute("avatar_url");  // 头像 URL

        // 检查用户是否已存在于数据库
        User user = userRepository.findByProviderAndProviderId(provider, providerId);
        if (user == null) {
            // 如果用户不存在,则保存用户信息到数据库
            user = new User(username, email, avatarUrl, provider, providerId);
            userRepository.save(user);
        }

        return oauth2User;  // 返回 OAuth2User 对象
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

关键点解析:

  • userRequest.getClientRegistration().getRegistrationId():获取当前登录的平台,如 "github" 或 "gitee"。
  • oauth2User.getAttribute("login"):获取平台的用户信息,不同平台的字段名可能不同,需要根据平台文档确定。
  • 用户信息持久化:使用 JPA 将用户信息保存到数据库中,支持后续操作。

# 6. OAuth2 登录的完整流程

完整流程如下:

  1. 用户点击第三方登录按钮,重定向到第三方授权页面(如 GitHub/Gitee)。
  2. 用户同意授权后,第三方返回授权码给应用。
  3. 应用使用授权码请求访问 Token。
  4. 通过访问 Token 获取用户信息,并将其注入到 Spring Security 上下文中。
  5. 将获取的用户信息保存到数据库。
  6. 用户登录成功,可以访问受保护的资源。

总结

通过结合 Spring Security 和 JPA,我们不仅实现了第三方登录,还能将用户信息持久化到数据库中,方便后续管理。在集成过程中,关注关键配置参数和自定义用户服务逻辑,可以确保集成顺利进行。

编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
Security 的 Session 与 Token 管理
Spring Security 集成 QQ 登录与 JWT 认证

← Security 的 Session 与 Token 管理 Spring Security 集成 QQ 登录与 JWT 认证→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式