Day977.除了授权码许可类型,OAuth 2.0还支持什么授权流程? -OAuth 2.0

news2024/10/6 0:30:27

除了授权码许可类型,OAuth 2.0还支持什么授权流程?

Hi,我是阿昌,今天学习记录的是关于除了授权码许可类型,OAuth 2.0还支持什么授权流程?的内容。

授权码许可的流程最完备、最安全没错儿,但它适合所有的授权场景吗?

在有些场景下使用授权码许可授权,是不是过于复杂了,是不是根本就没必要这样?

比如,小兔打单软件是京东官方开发的一款软件,那么小明在使用小兔的时候,还需要小兔再走一遍授权码许可类型的流程吗?肯定是不需要了。

授权码许可流程的特点?它通过授权码这种临时的中间值,让小明这样的用户参与进来,从而让小兔软件和京东之间建立联系,进而让小兔代表小明去访问他在京东店铺的订单数据。

现在小兔被“招安”了,是京东自家的了,是被京东充分信任的,没有“第三方软件”的概念了。同时,小明也是京东店铺的商家,也就是说软件和用户都是京东的资产

这时,显然没有必要再使用授权码许可类型进行授权了。但是呢,小兔依然要通过互联网访问订单数据的 Web API,来提供为小明打单的功能。

于是,为了保护这些场景下的 Web API,又为了让 OAuth 2.0 更好地适应现实世界的更多场景,来解决比如上述小兔软件这样的案例,OAuth 2.0 体系中还提供了资源拥有者凭据许可类型。


一、资源拥有者凭据许可

从“资源拥有者凭据许可”这个命名上,可能就已经理解它的含义了。

没错,资源拥有者的凭据,就是用户的凭据,就是用户名和密码

可见,这是最糟糕的一种方式。那为什么 OAuth 2.0 还支持这种许可类型,而且编入了 OAuth 2.0 的规范呢?

正如上面我提到的,小兔此时就是京东官方出品的一款软件,小明也是京东的用户,那么小明其实是可以使用用户名和密码来直接使用小兔这款软件的。原因很简单,那就是这里不再有“第三方”的概念了。但是呢,如果每次小兔都是拿着小明的用户名和密码来通过调用 Web API 的方式,来访问小明店铺的订单数据,甚至还有商品信息等,在调用这么多 API 的情况下,无疑增加了用户名和密码等敏感信息的攻击面。

如果是使用了 token 来代替这些“满天飞”的敏感信息,不就能很大程度上保护敏感信息数据了吗?这样,小兔软件只需要使用一次用户名和密码数据来换回一个 token,进而通过 token 来访问小明店铺的数据,以后就不会再使用用户名和密码了。


这种许可类型的流程,如下图所示:

图1 资源拥有者凭据许可类型的流程

步骤 1:当用户访问第三方软件小兔时,会提示输入用户名和密码。索要用户名和密码,就是资源拥有者凭据许可类型的特点。

步骤 2:这里的 grant_type 的值为 password,告诉授权服务使用资源拥有者凭据许可凭据的方式去请求访问。

Map<String, String> params = new HashMap<String, String>();
params.put("grant_type","password");
params.put("app_id","APPIDTEST");
params.put("app_secret","APPSECRETTEST");
params.put("name","NAMETEST");
params.put("password","PASSWORDTEST");

String accessToken = HttpURLClient.doPost(oauthURl,HttpURLClient.mapToStr(params));

步骤 3:授权服务在验证用户名和密码之后,生成 access_token 的值并返回给第三方软件。

if("password".equals(grantType)){
    String appSecret = request.getParameter("app_secret");
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if(!"APPSECRETTEST".equals(appSecret)){
        response.getWriter().write("app_secret is not available");
        return;
    }
    if(!"USERNAMETEST".equals(username)){
        response.getWriter().write("username is not available");
        return;
    }
    if(!"PASSWORDTEST".equals(password)){
        response.getWriter().write("password is not available");
        return;
    }
    String accessToken = generateAccessToken(appId,"USERTEST");//生成访问令牌access_token的值
    response.getWriter().write(accessToken);
}

到了这里,可以掌握到一个信息:如果软件是官方出品的,又要使用 OAuth 2.0 来保护我们的 Web API,那么就可以使用小兔软件的做法,采用资源拥有者凭据许可类型。

无论是我们的架构、系统还是框架,都是致力于解决现实生产中的各种问题的。除了资源拥有者凭据许可类型外,OAuth 2.0 体系针对现实的环境还提供了客户端凭据许可和隐式许可类型。


二、客户端凭据许可

如果没有明确的资源拥有者,换句话说就是,小兔软件访问了一个不需要用户小明授权的数据,比如获取京东 LOGO 的图片地址,这个 LOGO 信息不属于任何一个第三方用户,再比如其它类型的第三方软件来访问平台提供的省份信息,省份信息也不属于任何一个第三方用户。此时,在授权流程中,就不再需要资源拥有者这个角色了。

可以形象地理解为 “资源拥有者被塞进了第三方软件中” 或者 “第三方软件就是资源拥有者”。这种场景下的授权,便是客户端凭据许可,第三方软件可以直接使用注册时的 app_id 和 app_secret 来换回访问令牌 token 的值。

还是以小明使用小兔软件为例,来看下客户端凭据许可的整个授权流程,如下图所示:

图2 客户端凭据许可授权流程

另外一点呢,因为授权过程没有了资源拥有者小明的参与,小兔软件的后端服务可以随时发起 access_token 的请求,所以这种授权许可也不需要刷新令牌。

这样一来,客户端凭据许可类型的关键流程,就是以下两大步。

步骤 1:第三方软件小兔通过后端服务向授权服务发送请求,这里 grant_type 的值为 client_credentials,告诉授权服务要使用第三方软件凭据的方式去请求访问。

Map<String, String> params = new HashMap<String, String>();
params.put("grant_type","client_credentials");
params.put("app_id","APPIDTEST");
params.put("app_secret","APPSECRETTEST");

String accessToken = HttpURLClient.doPost(oauthURl,HttpURLClient.mapToStr(params));

步骤 2:在验证 app_id 和 app_secret 的合法性之后,生成 access_token 的值并返回。


String grantType = request.getParameter("grant_type");
String appId = request.getParameter("app_id");

if(!"APPIDTEST".equals(appId)){
    response.getWriter().write("app_id is not available");
    return;
}
if("client_credentials".equals(grantType)){
    String appSecret = request.getParameter("app_secret");
    if(!"APPSECRETTEST".equals(appSecret)){
        response.getWriter().write("app_secret is not available");
        return;
    }
    String accessToken = generateAccessToken(appId,"USERTEST");//生成访问令牌access_token的值
    response.getWriter().write(accessToken);
}

在获取一种不属于任何一个第三方用户的数据时,并不需要类似小明这样的用户参与,此时便可以使用客户端凭据许可类型。


三、隐式许可

再想象一下,如果小明使用的小兔打单软件应用没有后端服务,就是在浏览器里面执行的,比如纯粹的 JavaScript 应用,应该如何使用 OAuth 2.0 呢?

其实,这种情况下的授权流程就可以使用隐式许可流程,可以理解为第三方软件小兔直接嵌入浏览器中了。

在这种情况下,小兔软件对于浏览器就没有任何保密的数据可以隐藏了,也不再需要应用密钥 app_secret 的值了,也不用再通过授权码 code 来换取访问令牌 access_token 的值了。

因为使用授权码的目的之一,就是把浏览器和第三方软件的信息做一个隔离,确保浏览器看不到第三方软件最重要的访问令牌 access_token 的值。

因此,隐式许可授权流程的安全性会降低很多。在授权流程中,没有服务端的小兔软件相当于是嵌入到了浏览器中,访问浏览器的过程相当于接触了小兔软件的全部,因此我用虚线框来表示小兔软件,整个授权流程如下图所示:

图3 隐式许可授权流程

接下来,使用 Servlet 的 Get 请求来模拟这个流程,一起看看相关的示例代码。

步骤 1:用户通过浏览器访问第三方软件小兔。此时,第三方软件小兔实际上是嵌入浏览器中执行的应用程序。

步骤 2:这个流程和授权码流程类似,只是需要特别注意一点,response_type 的值变成了 token,是要告诉授权服务直接返回 access_token 的值。

会发现隐式许可流程是唯一在前端通信中要求返回 access_token 的流程。对,就这么 “大胆”,但 “不安全”

Map<String, String> params = new HashMap<String, String>();
params.put("response_type","token");//告诉授权服务直接返回access_token
params.put("redirect_uri","http://localhost:8080/AppServlet-ch02");
params.put("app_id","APPIDTEST");

String toOauthUrl = URLParamsUtil.appendParams(oauthUrl,params);//构造请求授权的URl
response.sendRedirect(toOauthUrl);

步骤 3:生成 acccess_token 的值,通过前端通信返回给第三方软件小兔。


String responseType = request.getParameter("response_type");
String redirectUri =request.getParameter("redirect_uri");
String appId = request.getParameter("app_id");
if(!"APPIDTEST".equals(appId)){
    return;
}

if("token".equals(responseType)){
    //隐式许可流程(模拟),DEMO CODE,注意:该流程全部在前端通信中完成
    String accessToken = generateAccessToken(appId,"USERTEST");//生成访问令牌access_token的值

    Map<String, String> params = new HashMap<String, String>();
    params.put("redirect_uri",redirectUri);
    params.put("access_token",accessToken);

    String toAppUrl = URLParamsUtil.appendParams(redirectUri,params);//构造第三方软件的回调地址,并重定向到该地址
    response.sendRedirect(toAppUrl);//使用sendRedirect方式模拟前端通信
}

如果你的软件就是直接嵌入到了浏览器中运行,而且还没有服务端的参与,并且还想使用 OAuth 2.0 流程的话,也就是像上面我说的小兔这个例子,那么便可以直接使用隐式许可类型了。


四、如何选择?

应该如何选择到底使用哪种授权许可类型呢?

这里,建议是,在对接 OAuth 2.0 的时候先考虑授权码许可类型,其次再结合现实生产环境来选择:

  • 如果小兔软件是官方出品,那么可以直接使用资源拥有者凭据许可;
  • 如果小兔软件就是只嵌入到浏览器端的应用且没有服务端,那就只能选择隐式许可;
  • 如果小兔软件获取的信息不属于任何一个第三方用户,那可以直接使用客户端凭据许可类型。

五、总结

现实世界总是有各种各样的变化,OAuth 2.0 也要适应这样的变化,所以才有了另外这三种许可类型。同时,关于如何来选择使用这些许可类型,给了一个建议。加上前面授权码许可类型,一共讲了 4 种授权许可类型,它们最显著的区别就是获取访问令牌 access_token 的方式不同。

最后,一张表格来对比下:

图4 OAuth 2.0的4种授权许可类型对比

除了上面这张表格所展现的 4 种授权许可类型的区别之外,记住以下两点。

  1. 所有的授权许可类型中,授权码许可类型的安全性是最高的。因此,只要具备使用授权码许可类型的条件,一定要首先授权码许可类型。
  2. 所有的授权许可类型都是为了解决现实中的实际问题,因此还要结合实际的生产环境,在保障安全性的前提下选择最合适的授权许可类型,比如使用客户端凭据许可类型的小兔软件就是一个案例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/768228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将大模型集成到语音识别系统中的例子

概述 本文旨在探索将大型语言模型&#xff08;LLMs&#xff09;集成到自动语音识别&#xff08;ASR&#xff09;系统中以提高转录准确性的潜力。 文章介绍了目前的ASR方法及其存在的问题&#xff0c;并对使用LLMs的上下文学习能力来改进ASR系统的性能进行了合理的动机论证。 本…

【分布式缓存】springboot整合jetcache使用详解

目录 一、前言 二、多级缓存问题 2.1 缓存分类 2.1.1 本地缓存 2.1.2 分布式缓存 2.2 独立缓存的问题 2.2.1 缓存雪崩问题 2.2.2 对宽带压力大 2.2.3 运行效率低 2.3 多级缓存方案 2.3.1 多级缓存实践方案推荐 三、jetcache介绍 3.1 jetcache概述 3.2 jetcache 特…

手写代码系列

(1)手写clearfix .clearfix:after{content:; display:table;clear:both;} (2) 手写圣杯模型 (3)手写深拷贝 递归 const obj3={age:20,name:xxx,address:{} }, arr:[a,b,c] function deeepClone(obj={}){} (4)手写画图解释原型链(class的原型和本质)

vue3 引入dataV 报错,使用patch-package记录插件包 node_modeule 修改记录。 vite 版DataV

开发数字大屏功能&#xff0c;引用dataV UI组件库比较好用&#xff0c;目前分为Vue2 和 Vue3 两个版本。 Vue2 --DataV版本 yarn add jiaminghi/data-viewVue3 --DataV版本 yarn add dataview/datav-vue3vite – --DataV版本 //不想动手改的&#xff0c;也可以使用此版本&a…

2、常用布局控件

首先,展开工具箱。注意这里打开的文件要是窗体文件,就是Form1,cs,否则工具箱列表将是空的。 然后选到容器,这里我们就可以看到常用的布局控件了。 使用的时候直接从左边拉到右边即可 注意:布局是支持嵌套的。 这里我们逐个介绍。 第一个是指针,这个不是布局控件,就是…

LCD-STM32液晶显示中英文-(7.字模及显示原理)

目录 字模介绍 什么是字模 字模的构成 字模显示原理 字模制作 如何制作字模 字模寻址公式 存储字模文件 字模介绍 什么是字模 有了编码&#xff0c;我们就能在计算机中处理、存储字符了&#xff0c;但是如果计算机处理完字符后直接以编码的形式输出&#xff0c;人类将难…

python解析器和pycharm编译器安装

python解析器下载地址&#xff1a;https://www.python.org/getit/ 注意事项&#xff1a; 1. 建议下载3.6以以上的版本&#xff0c; 2. 官网下载比较慢&#xff0c;可以自行寻找其它网站下载&#xff0c; 3. 建议使用.exe安装包方式下载安装 下载完成后双击运行 验证是否安装成功…

使用Python提取TripAdvisor数据:探索旅游的新途径

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 猫途鹰&#xff08;TripAdvisor&#xff09;是一个旅游点评网站&#xff0c;如果您想要爬取该网站的数据&#xff0c;需要了解该网站的访问规则和爬取限制。 环境使用: Python 3.8 Pycharm 代码实现 针对猫途鹰网站&#…

Echarts柱状图横向滚动,如何实现从后往前滚动

Echarts柱状图横向滚动&#xff0c;如何实现从后往前滚动 设置开始和结束的横坐标&#xff0c;设置产生横向滚动条

解决apkanalyzer.bat could NOT be found in D:\Download\Android SDK Tools!警告报错

appium安装过程中很可能出现以下警告报错&#xff0c;咱就按如下操作即可搞定&#xff01;&#xff01;&#xff01; apkanalyzer.bat could NOT be found in D:\Download\Android SDK Tools! 一、下载Command line tools 下载地址&#xff1a;​https://developer.android.g…

GAMES101 作业1

文章目录 作业内容构建视图矩阵&#xff08;View&#xff09;构建模型矩阵 (Model)构建透视矩阵&#xff08;Projection&#xff09;视口变换(Viewport transform)提高&#xff1a;将三角形绕任意过原点的轴旋转旋转过程中报错 作业内容 本次作业的任务是填写一个旋转矩阵和一…

大模型开发(五):实现Jupyter本地调用OpenAI API

全文共3000余字&#xff0c;预计阅读时间约15分钟 | 满满干货&#xff0c;建议收藏&#xff01; 大模型开发(五)&#xff1a;实现Jupyter本地调用OpenAI API OpenAI作为本轮大语言模型技术进步的先驱&#xff0c;其系列大型模型在效果上一直保持着领先。其推出的各类模型如文本…

【PDF】HTML通过dom节点生成pdf

1、简要描述 上一篇博客主要讲的是pdf文件转换成canvas&#xff0c;然后进行相关的画框截图操作。 【PDF】Canvas绘制PDF及截图 本篇博客主要讲html中dom如何生成pdf文件&#xff08;前端生成pdf&#xff09;&#xff0c;后端生成pdf当然也可以&#xff0c;原理也是将html网…

数据容器入门(str)

字符串是字符的容器&#xff0c;一个字符串可以存放任意数量的字符 字符串的特点&#xff1a; 作为数据容器&#xff0c;字符串有如下特点&#xff1a; 只可以存储字符串长度任意&#xff08;取决于内存大小&#xff09;支持下标索引允许重复字符串存在不可以修改&#xff08;…

智慧数据驱动:基于smardaten构建多维数据可视化大屏

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

网络虚拟化相关的Linux接口介绍

Linux拥有丰富的网络虚拟化功能&#xff0c;能被虚拟机&#xff0c;容器还有云网络使用。在这篇文章中&#xff0c;我会给出所有通用网络虚拟化接口的简要介绍。没有代码分析&#xff0c;只有简短的接口介绍和在Linux上的使用操作。这系列接口都可以使用ip link命令实现。 这篇…

reggie优化06-项目部署

1、部署架构 2、部署环境 3、部署前端 4、部署后端 修改图片位置&#xff0c;并push至仓库

Redis数据类型(2)

⭐ 作者简介&#xff1a;码上言 ⭐ 代表教程&#xff1a;Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容&#xff1a;个人博客系统 ⭐我的文档网站&#xff1a;http://xyhwh-nav.cn/ 文章目录 Redis数据类型1、Redis 键(key)1.1、KEYS pattern1.2、EXISTS k…

Vector - CANoe - VCDL与SomeIP

目录 一、基础介绍 二、vCDL介绍 1、vCDL工程创建 2、 vCDL编辑器关键字介绍 3、创建命名空间Datatype 接口示例 4、创建命名空间ICalculate 5、创建命名空间Participants 一、基础介绍 SomeIP作为车载以太网一个重要的组成部分&#xff0c;因为它的测试也是我们作为总…