后端与系统架构3541 字

一口气讲完OAuth2四种授权模式

·全库 563 / 611

《一口气讲完OAuth2四种授权模式》共 0.4 万字,通篇围绕 数据库、权限、安全、日志 展开,归在「后端与系统架构」这一层。

覆盖数据库权限安全日志场景Redis

适合给 AI 系统搭底座、要管得住的人

目录骨架(8 节)
  1. 应用场景
  2. 名词定义
  3. 认证流程
  4. 依赖引入
  5. 资源服务
  6. 认证服务
  7. 授权码模式
  8. 简化模式

示例代码

📎 附件:oauth-demo.zip(zip, 32KB)

原文链接:https://www.yuque.com/attachments/yuque/0/2024/zip/2424104/1715734317687-b7ebc1ea-727e-4d55-b751-0d1670d6bd0c.zip

jdk版本:1.8.0_181

​

本次分享内容

  1. OAuth2概念和流程
  2. OAuth2项目实战
  3. OAuth2四种授权模式(授权码模式、简化模式、密码模式、客户端模式)
  4. 总结

理论

OAuth是一个关于授权(authorization)的开放网络标准,用来授权第三方应用获取用户数据,是目前最流行的授权机制,它当前的版本是 2.0。

应用场景

假如你正在 “网站 A” 上冲浪,看到一篇帖子表示非常喜欢,当你情不自禁的想要点赞时,它会提示你进行登录操作。

打开登录页面你会发现,除了最简单的账户密码登录外,还为我们提供了微博、微信、QQ 等快捷登录方式。假设选择了快捷登录,它会提示我们扫码或者输入账号密码进行登录。

登录成功之后便会将 QQ / 微信的昵称和头像等信息回填到 “网站 A” 中,此时你就可以进行点赞操作了。

名词定义

在详细讲解oauth2之前,我们先来了解一下它里边用到的名词定义吧:

  • Client:客户端,它本身不会存储用户快捷登录的账号和密码,只是通过资源拥有者的授权去请求资源服务器的资源,即例子中的网站 A;
  • Resource Owner:资源拥有者,通常是用户,即例子中拥有 QQ / 微信账号的用户;
  • Authorization Server:认证服务器,可以提供身份认证和用户授权的服务器,即给客户端颁发token和校验token;
  • Resource Server:资源服务器,存储用户资源的服务器,即例子中的 QQ / 微信存储的用户信息;

认证流程

如图是oauth2官网的认证流程图,我们来分析一下:

  • A 客户端向资源拥有者发送授权申请;
  • B 资源拥有者同意客户端的授权,返回授权码;
  • C 客户端使用授权码向认证服务器申请令牌token;
  • D 认证服务器对客户端进行身份校验,认证通过后发放令牌;
  • E 客户端拿着认证服务器颁发的令牌去资源服务器请求资源;
  • F 资源服务器校验令牌的有效性,返回给客户端资源信息;

为了大家更好的理解,我们看下面这张图

到这儿,相信大家对理论知识已经掌握的差不多了,接下来我们就进入实战训练吧。

实战

在正式开始搭建项目之前我们先来做一些准备工作:要想使用oauth2的服务,我们得先创建几张表。

数据库

oauth2相关的建表语句可以参考官方初始化 sql,也可以查看项目中的 init.sql 文件

image.png

至于表结构,大家可以先大体了解下,其中字段的含义,在 init.sql 文件中已经做了说明。

  • oauth_client_details:存储客户端的配置信息,操作该表的类主要是JdbcClientDetailsService.java;
  • oauth_access_token:存储生成的令牌信息,操作该表的类主要是JdbcTokenStore.java;
  • oauth_client_token:在客户端系统中存储从服务端获取的令牌数据,操作该表的类主要是JdbcClientDetailsService.java;
  • oauth_code:存储授权码信息与认证信息,即只有grant_type为authorization_code时,该表才会有数据,操作该表的类主要是JdbcAuthorizationCodeServices.java;
  • oauth_approvals:存储用户的授权信息;
  • oauth_refresh_token:存储刷新令牌的refresh_token,如果客户端的grant_type不支持refresh_token,那么不会用到这张表,操作该表的类主要是JdbcTokenStore;

在oauth_client_details表中添加一条数据

client_id:cheetah_one //客户端名称,必须唯一
resource_ids:product_api //客户端所能访问的资源id集合,多个资源时用逗号(,)分隔
client_secret:$2a$10$h/TmLPvXozJJHXDyJEN22ensJgaciomfpOc9js9OonwWIdAnRQeoi //客户端的访问密码
scope:read,write //客户端申请的权限范围,可选值包括read,write,trust。若有多个权限范围用逗号(,)分隔
authorized_grant_types:client_credentials,implicit,authorization_code,refresh_token,password //指定客户端支持的grant_type,可选值包括authorization_code,password,refresh_token,implicit,client_credentials, 若支持多个grant_type用逗号(,)分隔
web_server_redirect_uri:http://www.baidu.com //客户端的重定向URI,可为空, 当grant_type为authorization_code或implicit时, 在Oauth的流程中会使用并检查与注册时填写的redirect_uri是否一致
access_token_validity:43200 //设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 12, 12小时)
autoapprove:false //设置用户是否自动Approval操作, 默认值为 'false', 可选值包括 'true','false', 'read','write'

资料里没有你的场景?

把你手上的数据和想解决的那个环节发上来,我们按具体情况回,不复述方法论。

发布需求