认证学习6 - Oauth2认证讲解、代码实现、演示



认证大全(想学习其他认证,请到此链接查看)

Oauth2认证 - 授权委托协议

讲解(Oauth2认证)

概述

参考视频: https://www.youtube.com/watch?v=T0h6A-M_WmI

参考书籍(有时间强烈建议去看一下通俗易懂而且有demo,不过不是java的而是nodejs版本): https://pan.baidu.com/s/1pPjgdWv-elnncb-Ckx7QZw?pwd=00dh === 提取码:00dh == OAuth2实战

官方定义规范文章(建议看=整体细节): https://datatracker.ietf.org/doc/rfc6749/
官方定义规范文章(建议看=Bearer令牌细节): https://datatracker.ietf.org/doc/rfc6750/

第三方网站的Oauth2的对接规范(微博-不想看官方直接看具体网站如何对接也大差不差): https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6

第三方网站的Oauth2的对接规范(码云-不想看官方直接看具体网站如何对接也大差不差): https://gitee.com/api/v5/oauth_doc#/

第三方网站的Oauth2的对接规范(Github-不想看官方直接看具体网站如何对接也大差不差): https://docs.github.com/cn/developers/apps/building-oauth-apps/authorizing-oauth-apps

作用: 用户A授权委托网站B(拿到用户A在网站C的令牌)可以使用用户A在网站C的信息 == 委托协议、跨系统授权的方案的标准

在这里插入图片描述

角色身份
角色身份
角色身份
用户A授权网站B可以使用用户A在网站C的信息==上图所示
资源所有(拥有)者:用户A(浏览器使用者)
服务提供商(资源服务器以及授权服务器==受保护资源):网站C == 一般是需多人熟知的一个站点(比如Github、Gittee、QQ等)
客户端(第三方应用=访问受保护资源的应用):网站B == 一般是仅少数人熟知的站点(比如个人网站)
授权所需信息(网站C提前定义)
应用名称:网站B
应用网站:网站C的地址
回调地址(URL):网站C认证成功后,自动跳转到网站B的哪个地址
客户端标识(client_id):网站C分配给网站B的标识ID
客户端密钥(client_secret):网站C分配给网站B进行加密的密钥
授予客⼾端的访问权
隐式授权没有
授权信息(令牌里面的内容含义由授权服务器自己规定)
access_token:客户端网站B用于访问网站C API的访问令牌 == 客户端无需知道令牌代表的具体内容
refresh_token:客户端网站B持有的访问令牌过期,用此刷新令牌向网站C获取新的访问令牌access_token
令牌相关的字段(客户端服务器持有并维护,用户无感知)
access_token:客户端访问资源服务器需要携带的令牌
expires_in:访问令牌的过期时间
token_type:访问令牌的使用方式
refresh_token:刷新令牌,用于由于访问令牌过期向授权服务器申请新的令牌而无需重新授权,如果刷新令牌也过期则需重新授权
expires_in_refresh:刷新令牌的过期时间,一般比expires_in大

在这里插入图片描述

在这里插入图片描述


官方RFC定义的Oauth2认证流程
在这里插入图片描述


官方RFC定义的Oauth2认证流程 == 结合访问token以及刷新token
在这里插入图片描述


微博Oauth2认证流程
在这里插入图片描述


码云Oauth2认证流程
在这里插入图片描述

客户端网站B利用reg刷新持有的网站C的access_token令牌(此过程无需用户参与)
在这里插入图片描述

授权(获取令牌)方式
建议,流程最严谨
Resource Owner Password Credentials Grant
Implicit Grant
Client Credentials Grant
方式
授权码方式
密码模式:遗留项目使用
简化模式:web浏览器设计
客户端模式:后台API服务消费设计
网站B给网站C的参数描述
response_type必须,授权方式:code(授权码类型)
client_id必须,网站B在网站C的客户端标识
redirect_uri可选,一般要求跟当时在网站C填写的回调地址一样
scope可选,请求资源范围,即需要申请的token需要什么权限
state可选,随机数

授权码授予(Authorization Code Grant)- 需浏览器用户、客户端、授权服务器三方参与

access_token: 网站C认证成功后,重定向到网站B的时候时会在url中携带过来code,然后网站B在服务器后台根据code,访问网站C的api获取用户的access_token

准则: 利用授权码或者刷新令牌获取访问令牌时,一旦校验错误,返回错误信息的响应报文,无论出于什么原因,授权服务器都必须将涉及到的授权码、刷新令牌信息删除,如授权码正确但是客户端ID错误、刷新令牌正确但客户端密钥错误的情况。

涉及令牌的信息==【由客户端持有、维护,用户无感知】
access_token:访问令牌,客户端用于访问资源服务器的资源
expires_in:访问令牌的过期时间
token_type:告知客户端请求资源时如何使用访问令牌
refresh_token:刷新令牌。访问令牌过期时则使用该令牌向授权服务器获取新的访问令牌
expires_in_refresh:刷新令牌的过期时间,时间长度一般比访问令牌的过期时间长

更详细的流程图-来自RFC文档协议图
在这里插入图片描述


更详细的流程图-来自书籍
在这里插入图片描述

隐式(简化)授予(Implicit Grant)- 需浏览器用户、客户端、授权服务器三方参与

access_token: 网站C认证成功后,重定向到网站B的时候时会在url中携带过来access_token

涉及令牌的信息==【由客户端持有、维护,用户无感知】
access_token:访问令牌,客户端用于访问资源服务器的资源
expires_in:访问令牌的过期时间
token_type:告知客户端请求资源时如何使用访问令牌

在这里插入图片描述

密码授予(Resource Owner Password Credentials Grant)- 需浏览器用户、客户端、授权服务器三方参与

access_token: 用户在网站B填入网站C的账户、密码信息,网站B使用网站C的API进行账号、密码校验,校验通过则返回用户的access_token

涉及令牌的信息==【由客户端持有、维护,用户无感知】
access_token:访问令牌,客户端用于访问资源服务器的资源
expires_in:访问令牌的过期时间
token_type:告知客户端请求资源时如何使用访问令牌
refresh_token:刷新令牌。访问令牌过期时则使用该令牌向授权服务器获取新的访问令牌
expires_in_refresh:刷新令牌的过期时间,时间长度一般比访问令牌的过期时间长

在这里插入图片描述

客户端授予(Client Credentials Grant)- 仅客户端、授权服务器两方参与(无浏览器用户参与)

access_token: 其实依然是密码授予模式,比如使用BasicAuth、DigestAuth,依然需要用户提供网站C的账户、密码信息

涉及令牌的信息==【由客户端持有、维护,用户无感知】
access_token:访问令牌,客户端用于访问资源服务器的资源
expires_in:访问令牌的过期时间
token_type:告知客户端请求资源时如何使用访问令牌

在这里插入图片描述

额外功能:客户端应用可自行注册到授权服务器(API接口方式)

背景: 无需用户、开发者干预,开发者事先对接好授权服务器的注册接口即可,程序启动部署自动注册

简易视图

在这里插入图片描述

参数信息
字段名字段值描述
redirect_uris⼀个URI字符串数组,在基于重定向的OAuth许可类型中使⽤,⽐如authorization_code 和implicit
token_endpoint_auth_method客⼾端在令牌端点上进⾏⾝份认证的⽅式
none客⼾端不在令牌端点上进身份认证,可能是因为客户端不使用令牌端点,或者使用令牌端点但它是公开客户端
client_secret_basic客户端使⽤HTTP Basic发送其客户端密钥。如果不指定且已为客户端颁发了密钥,则默认为此值
client_secret_post客⼾端使⽤表单参数发送客⼾端密钥
client_secret_jwt客户端会创建一个用客户端密钥进行对称签名的JSON Web令牌(JWT)
private_key_jwt客户端会创建一个用客户端私钥进行非对称签名的JSON Web令牌(JWT)。客户端需要在授权服务器上注册自己的公钥
grant_types客户端获取令牌所使用的许可类型。该字段使用的值与令牌端点上grant_type 参数使用的值相同
authorization_code授权码许可,客户端将资源拥有者引导至授权端点,获取授权码,然后将授权码发回⾄令牌端点。需要对应使⽤的response_type 为“code”
implicit隐式许可,客⼾端将资源拥有者引导⾄授权端点,直接获取令牌。需要对应使⽤的response_type 为“token”
password资源拥有者密码许可,客户端向资源拥有者索取他们的用户名和密码,用于在令牌端点上换取令牌
client_credentials客户端凭据许可,客户端使用自己的凭据获取令牌
refresh_token刷新令牌许可,在资源拥有者不在场的情况下,客户端使用刷新令牌获取新的访问令牌
urn:ietf:params:oauth:grant-type:jwt-bearerJWT断言许可,客户端通过出示带有特定声明的JWT来获取令牌
urn:ietf:params:oauth:grant-type:saml2-bearerSAML断言许可,客户端通过出示带有特定声明的SAML文档来获取令牌
response_types客户端使用的授权端点响应类型。该字段使用的值与response_type 参数使用的值相同
code授权码响应类型,该类型会返回授权码,该授权码会被传递至令牌端点用于获取令牌
token隐式响应类型,该类型会直接向重定向URI 返回令牌
client_name可读的客⼾端显⽰名称
client_uri指向客⼾端主⻚⾯的URI
logo_uri客户端图形标志的URI。授权服务器可以使用该URI向用户展示客户端的标志,但需要注意的是,获取图片URI资源可能会给用户带来安全和隐私方面的问题
scope客⼾端请求令牌时所有可⽤的权限范围。它的值是以空格分隔的字符串,与OAuth协议中的同名字段⼀样
contacts客⼾端负责⼈员的联系⽅式列表。通常是电⼦邮箱地址,但也可能是电话号码,即时通信地址或者其他联系⽅式
tos_uri⼀个可读⻚⾯的URI,该⻚⾯列出了客⼾端服务条款。这些条款描述了资源拥有者对客⼾端授权时要接受的契约关系
policy_uri⼀个可读⻚⾯的URI,该⻚⾯包含客⼾端的隐私策略。该策略描述了部署客⼾端的机构如何搜集、使⽤、保留以及公开资源拥有者的个⼈数据,包括通过授权API获取的数据
jwks_uri⼀个指向JSON Web密钥集合的URI,该密钥集合包含此客⼾端的公钥,可被授权服务器访问。该字段不能与jwks ⼀起使⽤。优先使⽤jwks_uri 字段,因为它能让客⼾端轮换密钥
jwks⼀个JSON Web密钥集合⽂档(JSON对象),包含此客⼾端的公钥。该字段不能与jwks_uri ⼀起使⽤。优先使⽤jwks_uri 字段,因为它能让客⼾端轮换密钥
software_id客⼾端软件的唯⼀标识符。该标识符在同⼀个客⼾端软件的所有实例上都是相同的
software_versionsoftware_id 字段所标识的客⼾端软件的版本标识。版本字符串对授权服务器是不透明的,也不会假设它具有特定格式
安全准则
安全整改1 - 严格遵守规则
保障授权服务器
1. 授权码使⽤⼀次之后将其销毁
2. 精确匹配的重定向URI校验 == 不要为了方便支持子域名、子路径因为多少都会有点漏洞
3. 留意在进⾏错误提⽰的过程中,信息有可能通过URI⽚段或者Referrer 头部遭泄露
令牌规则
1. 尽量使用https协议而不是http协议
2. 令牌默认权限范围设置尽量保守,需要更大的权限,客户端自行使用刷新token进行提权
3. 授权服务器的令牌持久化存储不要存明文
4. 令牌⽣命周期不宜过长
5. PKCE可⽤于提⾼授权码的安全性(看下面的流程图即可-很简单)
安全整改2 - 流程优化(PKCE)

讲解: code_challenge_method标识code_challenge、code_verifier校验关系,比如说code_challenge_method=sha-256,则授权服务器是校验 sha256(code_challenge) 与 code_verifier 是否一致,一致才给客户端生成令牌。当然code_challenge、code_verifier可以是一样,比对是否一致也行,主要看你校验策略

code_challenge_method值设置
sha256:sha256(code_challenge) 、code_verifier 两者是否一致
plain:code_challenge、code_verifier 两者是否一致

在这里插入图片描述

在这里插入图片描述

代码实现

oauth第三方客户端(类比csdn端(因为支持第三方登录-微信扫码登录)): https://gitee.com/changenen/oauth-client-project

oauth授权端、以及保护资源端(类比微信端): https://gitee.com/changenen/oauth-client-project

注意: 本demo只是实现oauth常用的一些功能,虽然看起来不难但是实现起来也是花了不少心血。更高级的功能比如自定义授权权限,客户端自行注册到授权服务器,pkce校验是否都没在代码中实现,如果有兴趣可自行参考前面说的《oauth2实战》书籍进行增强编写即可

oauth-client-project
关键部分

在这里插入图片描述

oauth-resource-project
关键部分

在这里插入图片描述

在这里插入图片描述

演示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值