作者:后端小肥肠
🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案
🍊 有疑问可私信或评论区联系我。
🥑 创作不易未经允许严禁转载。
姊妹篇:
【OAuth2系列】集成微信小程序登录到 Spring Security OAuth 2.0_spring security 微信小程序登录-CSDN博客
【OAuth2系列】Spring Cloud Gateway 作为OAuth2 Client接入第三方单点登录代码实践_spring gateway oauth2 client-CSDN博客
【Spring Security系列】5 次密码错误触发账号锁定?Spring Security 高效实现方案详解_springsecurity5.7.6自定义密码错误策略-CSDN博客
【Spring Security系列】10分钟实现 SpringSecurity + CAS 完美单点登录方案_spring-security-cas-CSDN博客
【Spring Security系列】如何用Spring Security集成手机验证码登录?五分钟搞定!_springsecurity短信验证码登录-CSDN博客
【Spring Security系列】基于Spring Security实现权限动态分配之菜单-角色分配及动态鉴权实践_spring secrity权限角色动态管理-CSDN博客
【Spring Security系列】基于Spring Security实现权限动态分配之用户-角色分配_spring security 角色-CSDN博客
【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索_spring security 微信小程序登录-CSDN博客
【Spring Security系列】Spring Security+JWT+Redis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客
目录
1. 前言
2. 什么是OAuth2?
3. OAuth 2.0 的授权方式应用场景
4.OAuth2.0中四种授权方式
4.1. 授权码模式
4.2. 简化模式
4.3. 密码模式
4.4. 客户端模式
5. OAuth2.0中表结构说明
5.1. oauth_client_details【核心表】
5.2. oauth_client_token
5.3. oauth_access_token
5.4. oauth_refresh_token
5.5. oauth_code
6. 结语
7. 参考链接
1. 前言
随着互联网的快速发展,用户数据的安全性和隐私保护变得尤为重要。为了解决第三方应用在访问用户资源时可能出现的安全问题,OAuth 2.0 成为当前最广泛使用的授权协议。它提供了一种安全、开放、标准化的方式,允许用户授权第三方应用访问其资源,而无需暴露敏感的账户信息。无论是常见的社交登录(如微信、Google 登录),还是系统间的安全对接,OAuth 2.0 都为现代应用程序提供了强大的支持。
在本文中,我们将全面解析 OAuth 2.0 的授权机制和应用场景,包括常用的四种授权方式以及相关的数据库表结构设计。通过实际的例子和详细的流程分析,希望能够帮助开发者快速掌握 OAuth 2.0 的核心概念和实现方法。
2. 什么是OAuth2?
OAuth 2.0 — OAuth
OAuth 2.0 是目前最流行的授权机制,用来授权第三方应用,获取用户数据。OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的规范标准。与以往的授权方式不同之处是OAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 OAuth 是开放的安全的,业界提供了 OAuth 的多种实现,如 Java、PHP、Ruby 等各种语言开发包,大大节约了程序员的时间,因而OAuth是简易的。很多大公司如 阿里、腾讯、 Google,Yahoo,Microsoft等都提供了 OAuth 认证服务,这些都足以说明 OAuth 标准逐渐成为开放资源授权的标准。OAuth 协议1.0版本过于复杂,目前发展到2.0版本,2.0版本已得到广泛应用。
3. OAuth 2.0 的授权方式应用场景
在实际开发中,OAuth 2.0 提供了灵活的授权机制,可以满足多种场景需求。为了更好地说明其使用方式,我们以一个在线教育平台为例,探讨 OAuth 2.0 的实际应用。
假设某在线教育平台需要整合第三方服务(如微信、钉钉、腾讯会议等),以实现以下功能:
- 学生通过微信授权登录并绑定学习日程到腾讯日历;
- 教师使用钉钉账号快速登录教学管理工具,查看课程安排和学员信息;
- 平台自动对接腾讯会议,为线上课堂创建和管理视频会议。
OAuth 2.0 在这个场景中可以帮助平台完成以下任务:
-
用户授权第三方访问资源:
学生希望将自己的学习日程同步到腾讯日历,但又不希望直接向平台提供腾讯账号和密码。通过 OAuth 2.0,学生可以在平台中点击“同步到腾讯日历”,系统跳转到腾讯的授权页面,学生登录并授权后,平台获取一个访问令牌。之后,平台通过访问令牌与腾讯日历 API 交互,完成学习日程的同步。 -
快速实现身份验证:
教师可以通过 OAuth 2.0 快速登录教学管理工具,无需专门注册在线教育平台的账号。例如,教师点击“使用钉钉登录”,系统会跳转到钉钉的授权页面进行身份验证。在教师授权后,钉钉返回一个访问令牌,平台据此确认用户身份并分配相应的权限(如查看课程安排、学员列表等)。 -
系统间安全对接:
在线教育平台需要与腾讯会议集成,以便为线上课堂创建视频会议。在这种系统对系统的交互中,OAuth 2.0 的客户端模式(Client Credentials Grant)可以实现平台和腾讯会议 API 的安全通信。平台通过提供自身的客户端凭据(如 Client ID 和 Client Secret)获取访问令牌,然后使用该令牌通过腾讯会议的接口完成会议的创建、更新或删除等操作。
通过以上场景可以看出,OAuth 2.0 的授权机制在平台中可以灵活适配,从学生的日程同步到教师的快速登录,再到系统间的安全对接,均能确保数据的安全性和访问的便利性。
4.OAuth2.0中四种授权方式
OAuth2.0 的授权方式一共有四种:
授权码模式(Authorization Code):功能最完整,流程最严密的授权模式。国内各大服务提供商(微信、QQ、微 博、淘宝 、百度)都采用此模式进行授权。可以确定是用户真正同意授权;而且令牌是认证服务器发放给第三方应用的服务器,而不是浏览器上。
简化模式(Implicit): 令牌是发放给浏览器的,oauth客户端运行在浏览器中 ,通过JS脚本去申请令牌。而不是发放给第三方应用的服务器。
密码模式(Resource Owner Password Credentials):将用户名和密码传过去,直接获取 access_token 。用户同意授权动作是在第三方应用上完成 ,而不是在认证服务器上。第三方应用申请令牌时,直接带着用户名密码去向 认证服务器申请令牌。这种方式认证服务器无法断定用户是否真的授权了,用户名密码可能是第三方应用盗取来 的。
客户端证书模式(Client credentials):用得少。当一个第三应用自己本身需要获取资源(而不是以用户的名 义),而不是获取用户的资源时,客户端模式十分有用。
4.1. 授权码模式
授权码模式是 OAuth 2.0 中一种常见的授权方式,适用于需要高度安全性、后端服务器参与的场景。以下是以 第三方网站 为例,结合流程图详细说明授权码模式的工作原理:
流程步骤
-
用户访问第三方网站资源并请求登录
用户打开 第三方网站,尝试访问某些需要用户登录授权的资源。此时,系统会引导用户跳转到认证服务器(如微信认证服务器)。 -
跳转到认证服务器进行登录
第三方网站 检测到用户未登录后,会将用户跳转到认证服务器(如微信认证服务器)的登录页面,要求用户进行身份验证。 -
用户登录并授权
用户在认证服务器的页面完成登录操作后,认证服务器会向用户展示授权请求页面,说明 第三方网站 需要访问哪些权限(如获取用户的基本信息)。用户确认授权后,认证服务器记录授权并生成一个授权码。 -
认证服务器返回授权码
授权码是一个临时的短期凭证,认证服务器会将其附带在用户跳转回 第三方网站 时的重定向 URI 中,并将其发送到 第三方网站 的客户端。 -
第三方网站使用授权码请求令牌
第三方网站 的后端服务器拿到授权码后,会向认证服务器的令牌接口发送请求,并附上自身的 Client ID 和 Client Secret 以验证身份。 -
认证服务器返回访问令牌
认证服务器验证授权码和客户端身份后,向 第三方网站 返回访问令牌(Access Token)。访问令牌是访问用户资源的凭证。 -
第三方网站使用令牌获取用户信息
第三方网站 使用访问令牌向资源服务器(如微信资源服务器)发起请求,获取用户的授权资源(如用户基本信息)。 -
资源服务器返回用户信息
资源服务器验证令牌合法性后,返回用户的授权信息(如用户名、邮箱等)给 第三方网站。 -
登录完成并显示用户信息
第三方网站 获取到用户信息后,将其存储在会话中,视为登录成功,并向用户显示相关信息。
授权码模式的特点
- 高安全性:授权码仅在短时间内有效,访问令牌只会在后端服务器存储,前端无法直接接触到敏感数据。
- 适用场景:适用于 Web 应用或需要后端支持的场景,例如需要与外部服务整合的复杂应用。
- 分工明确:前端负责引导用户登录授权,后端负责安全存储和使用访问令牌。
4.2. 简化模式
简化模式(Implicit Grant)是一种适用于 无后端支持 的客户端应用(如单页面应用,SPA)的授权方式。访问令牌直接返回给客户端,用于访问用户的资源。以下以 第三方单页面应用 为例,解析简化模式的流程。
流程步骤
-
用户访问单页面应用并请求登录
用户打开 第三方单页面应用,尝试访问需要授权的资源(例如用户个人信息、数据等)。 -
跳转到认证服务器进行登录
应用检测到用户未登录,会将用户引导至认证服务器的授权页面。此时,应用会携带 Client ID 和重定向 URI 等参数,表明这是一个授权请求。 -
用户登录并授权
用户在认证服务器的页面完成登录操作后,系统会展示一个授权请求页面,说明单页面应用需要的权限范围(例如访问用户信息)。用户确认授权后,认证服务器会生成一个访问令牌(Access Token)。 -
认证服务器直接返回访问令牌
认证服务器将访问令牌附带在重定向 URI 的哈希片段中,直接返回给单页面应用的前端客户端。例如:https://example.com/callback#access_token=xyz123&token_type=bearer&expires_in=3600
-
单页面应用提取访问令牌并存储
前端应用从重定向 URI 中提取出访问令牌(通常通过 JavaScript 处理),并将其存储在内存中或短期存储中(如浏览器的sessionStorage
)。 -
使用访问令牌请求资源服务器
单页面应用使用访问令牌向资源服务器发起请求,获取用户的授权数据(如用户名、头像等)。 -
资源服务器返回授权数据
资源服务器验证令牌合法性后,返回用户的授权数据给单页面应用。 -
完成登录并显示用户信息
单页面应用根据返回的数据更新界面,显示用户的登录信息和授权内容。
简化模式的特点
- 无后端参与:令牌直接发送到客户端,适用于纯前端应用(如 SPA)。
- 快速响应:减少了后端交互的步骤,用户体验流畅。
- 安全性低:访问令牌暴露在前端,容易被拦截或盗用,建议配合以下措施:
- 通过 HTTPS 确保传输安全。
- 将令牌存储在短期存储(如
sessionStorage
)中,而非长期存储(如localStorage
)。 - 配合短期有效的令牌(如令牌有效期为 1 小时以内)。
4.3. 密码模式
密码模式(Resource Owner Password Credentials Grant)允许用户直接将用户名和密码提供给客户端,以获取访问令牌。它的安全性较低,一般仅在高度信任的环境中使用,比如内部系统。以下以 第三方网站的管理系统 为例,解析密码模式的流程。
流程步骤
-
用户在客户端输入凭据
用户打开客户端应用(如第三方内部管理系统),并输入用户名和密码尝试登录。
-
客户端将凭据发送至认证服务器
客户端应用将用户输入的 用户名 和 密码,连同自身的 Client ID 和 Client Secret,通过后台请求发送到认证服务器。
请求参数示例:
POST /oauth/token HTTP/1.1 Host: auth-server.com Content-Type: application/x-www-form-urlencoded grant_type=password username=user123 password=pass123 client_id=client_id_example client_secret=client_secret_example
-
认证服务器验证凭据
认证服务器接收到请求后,会:
- 验证 用户名 和 密码 是否正确。
- 检查 Client ID 和 Client Secret 是否有效。
- 如果所有验证通过,则生成一个访问令牌(Access Token)。
-
认证服务器返回访问令牌
验证通过后,认证服务器返回访问令牌(Access Token)给客户端。
返回示例:
{ "access_token": "xyz123", "token_type": "bearer", "expires_in": 3600 }
-
客户端使用令牌请求资源服务器
客户端携带访问令牌,向资源服务器发起请求,获取用户的授权数据或受保护的资源。
请求示例:
GET /userinfo HTTP/1.1 Host: resource-server.com Authorization: Bearer xyz123
-
资源服务器返回授权数据
资源服务器验证令牌的合法性后,返回用户授权的资源(如用户信息或操作权限)。
-
完成授权流程并展示数据
客户端接收到用户数据后,展示相关内容(如登录成功后的用户信息)。
密码模式的特点
- 用户凭据直接暴露:客户端需要直接存储用户名和密码,安全性较低。
- 适用场景:适用于内部应用或高度信任的场景,如内部管理系统。
- 不推荐用于公开的客户端应用:建议仅在无法避免的情况下使用。
4.4. 客户端模式
客户端模式(Client Credentials Grant)用于服务之间的授权,不涉及用户参与。典型场景是服务端之间的通信,例如后台服务器与第三方 API 的对接。以下以 第三方网站 和 资源服务器 的对接为例,解析客户端模式的流程。
流程步骤
-
第三方网站向认证服务器发起请求
第三方网站 的后台服务器向认证服务器发送请求,附带自身的 Client ID 和 Client Secret。 -
认证服务器验证客户端身份
认证服务器验证客户端的 Client ID 和 Client Secret 是否正确,确认客户端的合法性。 -
认证服务器返回访问令牌
验证通过后,认证服务器向 第三方网站 返回访问令牌(Access Token)。 -
第三方网站使用访问令牌访问资源服务器
第三方网站 使用获取的访问令牌向资源服务器发起请求,获取所需的资源或数据(如服务状态、统计数据等)。 -
资源服务器返回授权数据
资源服务器验证令牌合法性后,返回请求的数据给 第三方网站。
客户端模式的特点
- 无用户参与:直接在服务之间完成授权,令牌只在后台使用。
- 适用场景:服务对服务的交互,例如后台系统调用 API、任务自动化。
- 安全性高:凭据和令牌存储在服务器端,减少了被窃取的风险。
5. OAuth2.0中表结构说明
建表语句
:
/*
SQLyog Ultimate v12.08 (64 bit)
MySQL - 8.0.16 : Database - security_authority
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Table structure for table `oauth_access_token` */
DROP TABLE IF EXISTS `oauth_access_token`;
CREATE TABLE `oauth_access_token` (
`token_id` varchar(255) DEFAULT NULL,
`token` longblob,
`authentication_id` varchar(255) DEFAULT NULL,
`user_name` varchar(255) DEFAULT NULL,
`client_id` varchar(255) DEFAULT NULL,
`authentication` longblob,
`refresh_token` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_access_token` */
/*Table structure for table `oauth_approvals` */
DROP TABLE IF EXISTS `oauth_approvals`;
CREATE TABLE `oauth_approvals` (
`userId` varchar(255) DEFAULT NULL,
`clientId` varchar(255) DEFAULT NULL,
`scope` varchar(255) DEFAULT NULL,
`status` varchar(10) DEFAULT NULL,
`expiresAt` datetime DEFAULT NULL,
`lastModifiedAt` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_approvals` */
/*Table structure for table `oauth_client_details` */
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
`client_id` varchar(255) NOT NULL,
`resource_ids` varchar(255) DEFAULT NULL,
`client_secret` varchar(255) DEFAULT NULL,
`scope` varchar(255) DEFAULT NULL,
`authorized_grant_types` varchar(255) DEFAULT NULL,
`web_server_redirect_uri` varchar(255) DEFAULT NULL,
`authorities` varchar(255) DEFAULT NULL,
`access_token_validity` int(11) DEFAULT NULL,
`refresh_token_validity` int(11) DEFAULT NULL,
`additional_information` varchar(255) DEFAULT NULL,
`autoapprove` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_client_details` */
/*Table structure for table `oauth_client_token` */
DROP TABLE IF EXISTS `oauth_client_token`;
CREATE TABLE `oauth_client_token` (
`token_id` varchar(255) DEFAULT NULL,
`token` longblob,
`authentication_id` varchar(255) DEFAULT NULL,
`user_name` varchar(255) DEFAULT NULL,
`client_id` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_client_token` */
/*Table structure for table `oauth_code` */
DROP TABLE IF EXISTS `oauth_code`;
CREATE TABLE `oauth_code` (
`code` varchar(255) DEFAULT NULL,
`authentication` varbinary(2550) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_code` */
/*Table structure for table `oauth_refresh_token` */
DROP TABLE IF EXISTS `oauth_refresh_token`;
CREATE TABLE `oauth_refresh_token` (
`token_id` varchar(255) DEFAULT NULL,
`token` longblob,
`authentication` longblob
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*Data for the table `oauth_refresh_token` */
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
5.1. oauth_client_details【核心表】
字段名 | 字段说明 |
---|---|
client_id | 主键,必须唯一,不能为空. 用于唯一标识每一个客户端(client); 在注册时必须填写(也可由服务 端自动生成). 对于不同的grant_type,该字段都是必须的. 在实际应用中的另一个名称叫 appKey,与client_id是同一个概念. |
resource_ids | 客户端所能访问的资源id集合,多个资源时用逗号(,)分隔,如: “unity-resource,mobile- resource”. 该字段的值必须来源于与security.xml中标签?oauth2:resource-server的属性 resource-id值一致. 在security.xml配置有几个?oauth2:resource-server标签, 则该字段可以 使用几个该值. 在实际应用中, 我们一般将资源进行分类,并分别配置对应 的?oauth2:resource-server,如订单资源配置一个?oauth2:resource-server, 用户资源又配置 一个?oauth2:resource-server. 当注册客户端时,根据实际需要可选择资源id,也可根据不同的 注册流程,赋予对应的资源id. |
client_secret | 用于指定客户端(client)的访问密匙; 在注册时必须填写(也可由服务端自动生成). 对于不同的 grant_type,该字段都是必须的. 在实际应用中的另一个名称叫appSecret,与client_secret是 同一个概念. |
scope | 指定客户端申请的权限范围,可选值包括read,write,trust;若有多个权限范围用逗号(,)分隔,如: “read,write”. scope的值与security.xml中配置的?intercept-url的access属性有关系. 如?intercept-url的配置为?intercept-url pattern="/m/**" access=“ROLE_MOBILE,SCOPE_READ”/>则说明访问该URL时的客户端必须有read权限范 围. write的配置值为SCOPE_WRITE, trust的配置值为SCOPE_TRUST. 在实际应该中, 该值一 般由服务端指定, 常用的值为read,write. |
authorized_grant_types | 指定客户端支持的grant_type,可选值包括 authorization_code,password,refresh_token,implicit,client_credentials, 若支持多个 grant_type用逗号(,)分隔,如: “authorization_code,password”. 在实际应用中,当注册时,该字 段是一般由服务器端指定的,而不是由申请者去选择的,最常用的grant_type组合有: “authorization_code,refresh_token”(针对通过浏览器访问的客户端); “password,refresh_token”(针对移动设备的客户端). implicit与client_credentials在实际中 很少使用. |
web_server_redirect_uri | 客户端的重定向URI,可为空, 当grant_type为authorization_code或implicit时, 在Oauth的流 程中会使用并检查与注册时填写的redirect_uri是否一致. 下面分别说明:当 grant_type=authorization_code时, 第一步 从 spring-oauth-server获取 'code’时客户端发 起请求时必须有redirect_uri参数, 该参数的值必须与 web_server_redirect_uri的值一致. 第 二步 用 ‘code’ 换取 ‘access_token’ 时客户也必须传递相同的redirect_uri. 在实际应用中, web_server_redirect_uri在注册时是必须填写的, 一般用来处理服务器返回的code, 验证 state是否合法与通过code去换取access_token值.在spring-oauth-client项目中, 可具体参考 AuthorizationCodeController.java中的authorizationCodeCallback方法.当 grant_type=implicit时通过redirect_uri的hash值来传递access_token值. 如:http://localhost:7777/spring-oauth-client/implicit#access_token=dc891f4a-ac88- 4ba6-8224-a2497e013865&token_type=bearer&expires_in=43199然后客户端通过JS等从 hash值中取到access_token值. |
authorities | 指定客户端所拥有的Spring Security的权限值,可选, 若有多个权限值,用逗号(,)分隔, 如: "ROLE_ |
access_token_validity | 设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间 值(60 * 60 * 12, 12小时). 在服务端获取的access_token JSON数据中的expires_in字段的值 即为当前access_token的有效时间值. 在项目中, 可具体参考DefaultTokenServices.java中属 性accessTokenValiditySeconds. 在实际应用中, 该值一般是由服务端处理的, 不需要客户端 自定义.refresh_token_validity 设定客户端的refresh_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 24 * 30, 30天). 若客户端的grant_type不包 括refresh_token,则不用关心该字段 在项目中, 可具体参考DefaultTokenServices.java中属 性refreshTokenValiditySeconds. 在实际应用中, 该值一般是由服务端处理的, 不需要客户端 自定义. |
additional_information | 这是一个预留的字段,在Oauth的流程中没有实际的使用,可选,但若设置值,必须是JSON格式的 数据,如:{“country”:“CN”,“country_code”:“086”}按照spring-security-oauth项目中对该字段 的描述 Additional information for this client, not need by the vanilla OAuth protocol but might be useful, for example,for storing descriptive information. (详见 ClientDetails.java的getAdditionalInformation()方法的注释)在实际应用中, 可以用该字段来 存储关于客户端的一些其他信息,如客户端的国家,地区,注册时的IP地址等等.create_time 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段) |
archived | 用于标识客户端是否已存档(即实现逻辑删除),默认值为’0’(即未存档). 对该字段的具体使用请 参考CustomJdbcClientDetailsService.java,在该类中,扩展了在查询client_details的SQL加上 archived = 0条件 (扩展字段) |
trusted | 设置客户端是否为受信任的,默认为’0’(即不受信任的,1为受信任的). 该字段只适用于 grant_type="authorization_code"的情况,当用户登录成功后,若该值为0,则会跳转到让用户 Approve的页面让用户同意授权, 若该字段为1,则在登录后不需要再让用户Approve同意授权 (因为是受信任的). 对该字段的具体使用请参考OauthUserApprovalHandler.java. (扩展字 段) |
autoapprove | 设置用户是否自动Approval操作, 默认值为 ‘false’, 可选值包括 ‘true’,‘false’, ‘read’,‘write’. 该 字段只适用于grant_type="authorization_code"的情况,当用户登录成功后,若该值为’true’或 支持的scope值,则会跳过用户Approve的页面, 直接授权. 该字段与 trusted 有类似的功能, 是 spring-security-oauth2 的 2.0 版本后添加的新属性. 在项目中,主要操作 oauth_client_details表的类是JdbcClientDetailsService.java, 更多的细节请参考该类. 也可 以根据实际的需要,去扩展或修改该类的实现. |
作用:
- 存储 OAuth2 客户端(Client) 的基本信息,如
client_id
和client_secret
,是所有授权过程的基础配置。 - 用于定义每个客户端的权限范围(scope)、授权模式(grant_type)、重定向 URI 等信息。
- 决定客户端可以访问哪些资源(
resource_ids
)、令牌有效期、以及是否需要用户授权(autoapprove
)。
5.2. oauth_client_token
字段名 | 字段说明 |
---|---|
create_time | 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段) |
token_id | 从服务器端获取到的access_token的值. |
token | 这是一个二进制的字段, 存储的数据是OAuth2AccessToken.java对象序列化后的二进制数据. |
authentication_id | 该字段具有唯一性, 是根据当前的username(如果有),client_id与scope通过MD5加密生成的. 具体实现请参考DefaultClientKeyGenerator.java类. |
user_name | 登录时的用户名 |
client_id |
作用:
- 存储客户端特定的访问令牌(
token
)及其相关信息。 - 用于客户端使用特定的
access_token
访问资源服务器时快速验证。
5.3. oauth_access_token
字段名 | 字段说明 |
---|---|
create_time | 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段) |
token_id | 从服务器端获取到的access_token的值. |
token | 这是一个二进制的字段, 存储的数据是OAuth2AccessToken.java对象序列化后的二进制数据. |
authentication_id | 该字段具有唯一性, 是根据当前的username(如果有),client_id与scope通过MD5加密生成的. 具体实现请参考DefaultClientKeyGenerator.java类. |
user_name | 登录时的用户名 |
client_id | |
authentication | 存储将OAuth2Authentication.java对象序列化后的二进制数据. |
refresh_token | 该字段的值是将refresh_token的值通过MD5加密后存储的. 在项目中,主要操作oauth_access_token表的对象是JdbcTokenStore.java. 更多的细节请参考该类 |
作用:
- 存储 访问令牌(Access Token) 及其关联的身份验证信息。
- 用于用户访问资源服务器时,验证
access_token
的合法性和有效期。
5.4. oauth_refresh_token
字段名 | 字段说明 |
---|---|
create_time | 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段) |
token_id | 该字段的值是将refresh_token的值通过MD5加密后存储的. |
token | 存储将OAuth2RefreshToken.java对象序列化后的二进制数据 |
authentication | 存储将OAuth2RefreshToken.java对象序列化后的二进制数据 |
作用:
- 存储 刷新令牌(Refresh Token),用于在访问令牌过期后重新获取新的令牌。
- 与
oauth_access_token
表配合使用,提供令牌刷新机制。
5.5. oauth_code
字段名 | 字段说明 |
---|---|
create_time | 数据的创建时间,精确到秒,由数据库在插入数据时取当前系统时间自动生成(扩展字段) |
code | 存储服务端系统生成的code的值(未加密). |
authentication | 存储将AuthorizationRequestHolder.java对象序列化后的二进制数据. |
作用:
- 存储 授权码(Authorization Code),在授权码模式中,
code
是客户端用来交换访问令牌的临时凭据。 - 授权码模式特有的表,用于记录生成的
code
和相关的身份验证信息。
6. 结语
OAuth 2.0 作为现代应用开发中重要的授权机制,为用户与第三方应用之间提供了安全可靠的授权方式。从授权码模式到简化模式,再到密码模式和客户端模式,每种方式都能灵活适配不同场景需求。通过合理选择授权模式并结合安全措施(如 HTTPS 和短期令牌),可以有效保障用户数据的安全性。希望本文能够帮助开发者快速理解 OAuth 2.0 的核心概念和实现,为构建安全可靠的应用提供指导。
7. 参考链接
数据库表说明(oauth.ddl)