SAS-Github-Gitee-Login
一、前言
1. 什么是联合身份认证?
通过Spring Security OAuth2 Client(Login)模块集成第三方登录至自己的认证服务中,使用联合身份认证只需要请求认证服务,不通过前端来跳转三方的授权申请链接,而是统一通过认证服务来跳转,只需要维护Spring Authorization Server中身份认证提供商的关系即可。
2. 为什么要使用联合身份认证?
现在项目中都会集成一些三方登录,如Github、Gitee、微信、QQ平台提供的授权登录,如果手动集成则每种三方登录都要提供一个回调接口,自己实现通过code换取token,再用token获取用户信息的一个过程,但是这些内容Security OAuth2 Client都已经实现了,只要符合OAuth2的标准都可以使用这一套实现,不需要自己再造轮子了。
关于Security OAuth2 Client的对接过程及原理已经在Spring Authorization Server入门 (八) Spring Boot引入Security OAuth2 Client对接认证服务中说过了,今天就不细讲了,会重点讲一下如何获取和处理用户信息。 先来看一下文档,文档中说明了OAuth2 Login的一些配置,其中就有设置获取用户信息的服务,如下

再来详细看一下关于OAuth2UserService的详细介绍

发现OAuth2UserService有一个默认实现DefaultOAuth2UserService,它是通过RestOperations的实例请求用户的基础信息, 也说明了该类中可自定义的一些配置,例如请求参数转换、响应数据处理。
虽然上边说明了如何自定义OAuth2UserService,但是本人在查看源码时发现框架会先从配置中获取,获取不到会从ioc中获取,ioc中没有就初始化一个,如下所示

所以也支持以注入ioc中的方式去配置一个OAuth2UserService。
再来看一下OAuth2UserService中loadUser方法被调用的地方

OidcAuthorizationCodeAuthenticationProvider和OAuth2LoginAuthenticationProvider中都有调用,分别看一下这两个provider之间的逻辑,看看它们的区别


发现Oidc是需要有openid的scope才会被处理,而OAuth2开头的这个是在scope中未包含openid才会去处理。细看之后发现它们里边注入的OAuth2UserService的实例不一样,处理oidc登录的实例是OidcUserService,处理普通oauth登录的是DefaultOAuth2UserService,这是Security OAuth2 Client针对OAuth与OpenId connect两种登录方式的处理,在之前也有提到过,当scope中包含openid时本次就是openid connect登录,获取token后会响应idToken,里边包含了用户信息,所以这里会有两种处理。同 理,如果我们要自定义这两个service的话也需要实现这两个service,提高兼容性。
二、编码
1. 前期准备说明
-
今天主要演示Gitee与GitHub的oauth登录,所以需要先在各平台注册好所需的第三方应用。
-
初始化三方用户账号表
2. 编码流程说明
- 引入Security OAuth2 Client依赖,给认证服务添加一个“客户端”的身份
- 编写自定义
OAuth2UserService,来处理三方登录的用户信息 - 使用策略模式编写一套用户信息转换类,将三方用户信息转成自己系统里的用户信息并储存
- 编写联合身份认证自定义token处理,当使用openId Connect登录时将用户信息写入idToken中
- 更新认证服务配置类,添加联合身份认证配置
- 登录页面添加三方登录入口
开始编码之前放一下官方的联合身份认证示例
3. 初始化三方用户账号表
如果之前引入过需重新引入,表结构有变化
DROP TABLE IF EXISTS `oauth2_third_account`;
CREATE TABLE `oauth2_third_account`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`user_id` int(11) NULL DEFAULT NULL COMMENT '用户表主键',
`unique_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '三方登录唯一id',
`third_username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '三方用户的账号',
`credentials` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '三方登录获取的认证信息(token)',
`credentials_expires_at` datetime(0) NULL DEFAULT NULL COMMENT '三方登录获取的认证信息过期时间',
`avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '三方账号头像url',
`type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '三方登录类型',
`blog` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '博客地址',
`location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '地址',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '绑定时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '三方登录账户信息表' ROW_FORMAT = Dynamic;
4. 开始编码
1. 引入Security OAuth2 Client
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>