Day976.如何安全、快速地接入OAuth 2.0? -OAuth 2.0

news2024/11/25 19:20:38

如何安全、快速地接入OAuth 2.0?

Hi,我是阿昌,今天学习记录的是关于如何安全、快速地接入OAuth 2.0?的内容。

授权服务将 OAuth 2.0 的复杂性都揽在了自己身上,这也是授权服务为什么是 OAuth 2.0 体系的核心的原因之一。

虽然授权服务做了大部分工作,但是呢,在 OAuth 2.0 的体系里面,除了资源拥有者是作为用户参与,还有另外两个系统角色,也就是第三方软件和受保护资源服务。

在这两个角色的角度,看看它们应该做哪些工作,才能接入到 OAuth 2.0 的体系里面呢?

现在,,作为第三方软件的小兔和京东的受保护资源服务,具体需要着重处理哪些工作吧。

注:为了脱敏,在下面的讲述中,只是把JD商家开放平台作为一个角色使用,以便有场景感。


一、构建第三方软件应用

如果要基于京东商家开放平台构建一个小兔打单软件的应用,小兔软件的研发人员应该做哪些工作?

是不是要到京东商家开放平台申请注册为开发者,在成为开发者以后再创建一个应用,之后就开始开发了,对吧?没错,一定是这样的流程。

那么,开发第三方软件应用的过程中,需要重点关注哪些内容呢?

总结下,这些内容包括 4 部分,分别是:

  • 注册信息
  • 引导授权
  • 使用访问令牌
  • 使用刷新令牌。开发第三方软件应用,应该关注的内容

1、注册信息。

首先,小兔软件只有先有了身份,才可以参与到 OAuth 2.0 的流程中去。

也就是说,小兔软件需要先拥有自己的 app_idapp_serect 等信息,同时还要填写自己的回调地址 redirect_uri、申请权限等信息

这种方式的注册呢,有时候也称它为静态注册,也就是小兔软件的研发人员提前登录到京东商家开放平台进行手动注册,以便后续使用这些注册的相关信息来请求访问令牌。

2、引导授权。

当用户需要使用第三方软件,来操作其在受保护资源上的数据,就需要第三方软件来引导授权。比如,小明要使用小兔打单软件来对店铺里面的订单发货打印,那小明首先访问的一定是小兔软件(原则上是直接访问第三方软件,在后面服务市场这种场景的时候,会有稍微不同),不会是授权服务,更不会是受保护资源服务。

但是呢,小兔软件需要小明的授权,只有授权服务才能允许小明这样做。所以呢,小兔软件需要 “配合” 小明做的第一件事儿,就是将小明引导至授权服务,如下面代码所示。

让用户为第三方软件授权,得到了授权之后,第三方软件才可以代表用户去访问数据。

也就是说,小兔打单软件获得授权之后,才能够代表小明处理其在京东店铺上的订单数据。

//将用户重定向到授权地址,进行授权
String oauthUrl = "http://localhost:8081/OauthServlet-ch03?reqType=oauth";
response.sendRedirect(toOauthUrl);

3、使用访问令牌

拿到令牌后去使用令牌,才是第三方软件的最终目的。

看看如何使用令牌。目前 OAuth 2.0 的令牌只支持一种类型,那就是 bearer 令牌,也就是之前讲到的可以是任意字符串格式的令牌

官方规范给出的使用访问令牌请求的方式,有三种,分别是:

  • Form-Encoded Body Parameter(表单参数)
POST /resource HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
access_token=b1a64d5c-5e0c-4a70-9711-7af6568a61fb
  • URI Query Parameter(URI 查询参数)
GET /resource?access_token=b1a64d5c-5e0c-4a70-9711-7af6568a61fb HTTP/1.1
Host: server.example.com
  • Authorization Request Header Field(授权请求头部字段)
GET /resource HTTP/1.1
Host: server.example.com
Authorization: Bearer b1a64d5c-5e0c-4a70-9711-7af6568a61fb

也就是说,这三种方式都可以请求到受保护资源服务。

采用哪种方式最合适呢?

根据 OAuth 2.0 的官方建议,系统在接入 OAuth 2.0 之前信息传递的请求载体是 JSON 格式的,那么如果继续采用表单参数提交的方式,令牌就无法加入进去了,因为格式不符。如果这时采用参数传递的方式呢,整个 URI 会被整体复制,安全性是最差的

请求头部字段的方式就没有上述的这些“烦恼”,因此官方的建议是采用 Authorization 的方式来传递令牌。

但是,建议采用表单提交,也就是 POST 的方式来提交令牌,类似如下代码所示。原因是这样的,从官方的建议中也可以看出,它指的是在接入 OAuth 2.0 之前,如果已经采用了 JSON 数据格式请求体的情况下,不建议使用表单提交

但是,刚开始的时候,只要三方软件和平台之间约束好了,大家一致采用表单提交,就没有任何问题了。

因为表单提交的方式在保证安全传输的同时,还不需要去额外处理 Authorization 头部信息。

String protectedURl="http://localhost:8082/ProtectedServlet-ch03";
Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("app_id","APPID_RABBIT");
paramsMap.put("app_secret","APPSECRET_RABBIT");
paramsMap.put("token",accessToken);

String result = HttpURLClient.doPost(protectedURl,HttpURLClient.mapToStr(paramsMap));

4、使用刷新令牌

如果访问令牌过期了,小兔软件总不能立马提示并让小明重新授权一次,否则小明的体验将会非常不好。为了解决这个问题呢,就用到了刷新令牌。使用刷新令牌的方式跟使用访问令牌是一样的,具体可以参照上面讲的访问令牌的方式。

关于刷新令牌的使用,最需要关心的是,什么时候你会来决定使用刷新令牌。在小兔打单软件收到访问令牌的同时,也会收到访问令牌的过期时间 expires_in

一个设计良好的第三方应用,应该将 expires_in 值保存下来并定时检测;如果发现 expires_in 即将过期,则需要利用 refresh_token 去重新请求授权服务,以便获取新的、有效的访问令牌。这种定时检测的方法可以提前发现访问令牌是否即将过期。

此外,还有一种方法是“现场”发现。也就是说,比如小兔软件访问小明店铺订单的时候,突然收到一个访问令牌失效的响应,此时小兔软件立即使用 refresh_token 来请求一个访问令牌,以便继续代表小明使用他的数据。

  • 综合来看的话,定时检测的方式,需要额外开发一个定时任务;
  • “现场”发现,就没有这种额外的工作量啦。

具体采用哪一种方式,可以结合自己的实际情况。不过呢,还是建议你采用定时检测这种方式,因为它可以带来“提前量”,以便让有更好的主动性,而现场发现就有点被动了。

说到这里,刷新令牌是一次性的,使用之后就会失效,但是它的有效期会比访问令牌要长。这个时候可能会想到,如果刷新令牌也过期了怎么办?在这种情况下,就需要将刷新令牌和访问令牌都放弃,相当于回到了系统的初始状态,只能让用户小明重新授权了。

总结下,在构建第三方应用时,需要重点关注的就是注册、授权、访问令牌、刷新令牌。


二、服务市场中的第三方应用软件

在构建第三方应用的引导授权时,说用户第一次“触摸”到的一定是第三方软件,但这并不是绝对的。这个不绝对,就发生在服务市场这样的场景里。

那什么是服务市场呢?

说白了,就是你开发的软件,比如小兔打单软件、店铺装修软件等,都发布到这样一个“市场”里面售卖。

这样,当用户购买了这些软件之后,就可以在服务市场里面看到有个“立即使用”的按钮。点击这个按钮,用户就可以直接访问自己购买的第三方软件了。

比如,京东的京麦服务市场里有个“我的服务”目录,里面就存放了我购买的打单软件。

小明就可以直接点击“立即使用”,继而进入小兔打单软件,如下图所示。

京麦服务市场“我的服务”
那么,这里需要注意的是,作为第三方开发者来构建第三方软件的时候,在授权码环节除了要接收授权码 code 值之外,还要接收用户的订购相关信息,比如服务的版本号、服务代码标识等信息。好了,以上就是关于构建第三方软件时需要注意的一些细节问题了.


三、构建受保护资源服务

在整个开放授权的环境中,受保护资源最终指的还是 Web API,比如说,访问头像的 API、访问昵称的 API。对应到打单软件中,受保护资源就是订单查询 API、批量查询 API 等。

在互联网上的系统之间的通信,基本都是以 Web API 为载体的形式进行。因此呢,当说受保护资源被授权服务保护着时,实际上说的是授权服务最终保护的是这些 Web API。

在构建受保护资源服务的时候,除了基本的要检查令牌的合法性,还需要做些什么呢?认为最重要的就是权限范围了。

在处理受保护资源服务中的逻辑的时候,校验权限的处理会占据很大的比重。访问令牌递过来,肯定要多看看令牌到底能操作哪些功能、又能访问哪些数据吧。

现在,把这些权限的类别总结归纳下来,最常见的大概有以下几类。

3类权限类别
这些权限是如何使用的。

  1. 不同的权限对应不同的操作。
    这里的操作,其实对应的是 Web API,比如目前京东商家开放平台提供有查询商品 API、新增商品 API、删除商品 API 这三种。如果小兔软件请求过来的一个访问令牌 access_token 的 scope 权限范围只对应了查询商品 API、新增商品 API,那么包含这个 access_token 值的请求,就不能执行删除商品 API 的操作
    //不同的权限对应不同的操作
    String[] scope = OauthServlet.tokenScopeMap.get(accessToken);
    StringBuffer sbuf = new StringBuffer();
    for(int i=0;i<scope.length;i++){
        sbuf.append(scope[i]).append("|");
    }
    
    if(sbuf.toString().indexOf("query")>0){
        queryGoods("");
    }
    
    if(sbuf.toString().indexOf("add")>0){
        addGoods("");
    }
    
    if(sbuf.toString().indexOf("del")>0){
        delGoods("");
    }
    
  2. 不同的权限对应不同的数据。
    这里的数据,就是指某一个 API 里包含的属性字段信息。比如,有一个查询小明信息的 API,返回的信息包括 Contact(email、phone、qq)、Like(Basketball、Swimming)、Personal Data(sex、age、nickname)。如果小兔软件请求过来的一个访问令牌 access_token 的 scope 权限范围只对应了 Personal Data,那么包含该 access_token 值的请求就不能获取到 Contact 和 Like 的信息,关于这部分的代码,实际跟不同权限对应不同操作的代码类似。看到这里,你就明白了,这种权限范围的粒度要比“不同的权限对应不同的操作”的粒度要小。这正是遵循了最小权限范围原则。
  3. 不同的用户对应不同的数据。
    这种权限是什么意思呢?其实,这种权限实际上只是换了一种维度,将其定位到了用户上面。一些基础类信息,比如获取地理位置、获取天气预报等,不会带有用户归属属性,也就是说这些信息并不归属于某个用户,是一类公有信息。对于这样的信息,平台提供出去的 API 接口都是“中性”的,没有用户属性。但是,更多的场景却是基于用户属性的。还是以小兔打单软件为例,商家每次打印物流面单的时候,小兔打单软件都要知道是哪个商家的订单。这种情况下,商家为小兔软件授权,小兔软件获取的 access_token 实际上就包含了商家这个用户属性。京东商家开放平台的受保护资源服务每次接收到小兔软件的请求时,都会根据该请求中 access_token 的值找到对应的商家 ID,继而根据商家 ID 查询到商家的订单信息,也就是不同的商家对应不同的订单数据
    //不同的用户对应不同的数据
    String user = OauthServlet.tokenMap.get(accessToken);
    queryOrders(user);
    

在上面讲三种权限的时候,实际上都属于一个系统提供了查询、添加、删除这样的所有服务。

此时可能会想到,现在的系统不已经是分布式系统环境了么,如果有很多个受保护资源服务,比如提供用户信息查询的用户资源服务、提供商品查询的商品资源服务、提供订单查询的订单资源服务,那么每个受保护资源服务岂不是都要把上述的权限范围校验执行一遍吗,这样不就会有大量的重复工作产生么?

为了应对这种情况,应该有一个统一的网关层来处理这样的校验,所有的请求都会经过 API GATEWAY 跳转到不同的受保护资源服务。这样呢,

就不需要在每一个受保护资源服务上都做一遍权限校验的工作了,而只需要在 API GATEWAY 这一层做权限校验就可以了。

系统结构如下图所示。
由统一的网关层处理权限校验


四、总结

总结下来,能够记住以下两点。

  1. 对于第三方软件,比如小兔打单软件来讲,它的主要目的就是获取访问令牌,使用访问令牌,这当然也是整个 OAuth 2.0 的目的,就是让第三方软件来做这两件事。在这个过程中需要强调的是,第三方软件在使用访问令牌的时候有三种方式,建议在平台和第三方软件约定好的前提下,优先采用 Post 表单提交的方式。
  2. 受保护资源系统,比如小兔软件要访问开放平台的订单数据服务,它需要注意的是权限的问题,这个权限范围主要包括:
    • 不同的权限会有不同的操作
    • 不同的权限也会对应不同的数据
    • 不同的用户也会对应不同的数据。

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

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

相关文章

企业为什么纷纷推崇数字化管理?

企业提倡或推崇数字化管理&#xff0c;通常是因为几个原因&#xff1a; 效率和生产力&#xff1a;数字管理系统简化流程并自动执行重复任务&#xff0c;从而提高效率和生产力。数字工具可以更快地输入、检索和分析数据&#xff0c;减少人工工作和人为错误。这种效率使企业能够在…

STM32速成笔记—Flash闪存

文章目录 一、Flash简介二、STM32F1的Flash三、Flash操作步骤四、程序设计4.1 读取数据4.2 写入数据&#xff08;不检查&#xff09;4.3 写入数据&#xff08;检查&#xff09; 五、注意事项 一、Flash简介 快闪存储器&#xff08;flash memory&#xff09;&#xff0c;是一种…

物理与IP环境的重要性:打造稳定可靠的亚马逊测评环境

在亚马逊平台上进行测评补单、撸卡和撸货等活动&#xff0c;首要问题是确保环境的安全性和稳定性。一个稳定的环境是进行测评和撸卡的基础&#xff0c;如果无法解决安全性问题&#xff0c;那么从事这些项目就不值得。在环境技术研发领域已经有六七年的经验&#xff0c;在早期测…

红利期已过?2023跨境电商还吃香吗?亚马逊还能做吗?

2022年&#xff0c;由于疫情反复和外部因素的影响&#xff0c;跨境电商的情况并不乐观。但这并不意味着跨境电商已经走到了绝境。随着贸易全球化的深入发展&#xff0c;平台规则不断完善&#xff0c;国家相继出台最新的扶持政策&#xff0c;为跨境电商企业带来了更多的发展机遇…

Spring Boot 中的 Zookeeper 分布式锁

Spring Boot 中的 Zookeeper 分布式锁 分布式锁是分布式系统中常用的一个同步工具&#xff0c;它可以在多个进程之间协调访问共享资源&#xff0c;避免数据不一致或重复处理。在分布式环境中&#xff0c;由于网络通信的延迟和节点故障等原因&#xff0c;传统的锁机制无法满足需…

MES与ERP系统的生产计划管理到底有什么不同?

MES 的生产计划管理与 ERP 的生产计划管理到底有什么不同&#xff1f; 生产计划管理是企业发展的重要一环&#xff0c;对于提升企业生产效率&#xff0c;提高客户满意度&#xff0c;降低成本&#xff0c;提高客户满意度等方面都有重要意义。 我们首先来看MES和ERP生产计划管理…

Cisco Catalyst 9000 Series Switches, IOS-XE Release Dublin-17.11.1 ED

Cisco Catalyst 9000 Series Switches, IOS-XE Release Dublin-17.11.1 ED Cisco Catalyst 9000 交换产品系列 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-9000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;…

Vox-E: Text-guided Voxel Editing of 3D Objects(3D目标的文本引导体素编辑)

Vox-E: Text-guided Voxel Editing of 3D Objects &#xff08;3D目标的文本引导体素编辑&#xff09; Paper&#xff1a;https://readpaper.com/paper/1705264952657440000 Code&#xff1a;http://vox-e.github.io/ 原文链接&#xff1a;Vox-E: 3D目标的文本引导体素编辑 &…

如何写出高效的软件测试用例,测试人都用得到

要编写出高效的测试用例&#xff0c;需要搞清楚什么是测试用例&#xff0c;以及如何编写出高效的测试用例&#xff1f;接下来将从以下几个部分来进行展开 1、什么是测试用例 2、如何编写测试用例 一、什么是测试用例 测试用例 &#xff1a;为了特定目的而设计的由一组测试输…

【el-tree大量数据卡顿解决】el-tree利用懒加载解决大数据量卡顿问题,el-tree懒加载回显方法

描述 问题是这样&#xff1a;我的项目中&#xff0c;有一个角色管理的页面。以前的老代码&#xff0c;直接用el-tree渲染的树形结构&#xff0c;勾选设置对应的权限。其他的部门倒是还好&#xff0c;但是涉及到老板的部门设置的时候&#xff0c;由于我们这边的权限太多&#x…

ESP32开发:1、环境搭建(基于vscode+ESP-IDF)

1、ESP-IDF ESP-IDF提供操作ESP32芯片的API函数&#xff0c;供用户编写的用户程序调用。当用户程序编写好后&#xff0c;ESP-IDF需要借助一系列编译工具才能将用户程序API函数编译成能运行在ESP32上的二进制文件。 如上图所示这个1个G左右大的压缩包就是ESP-IDF。如果电脑上已经…

sslTrus (RSA) OV CA

sslTrus (RSA) OV CA品牌证书是建立在Sectigo CA机构的一种面向中国大陆的PKI定制中级根证书服务&#xff0c;OCSP国内本地网络优化&#xff0c;更适合中国网络。采取的Sectigo根证书建立的信任&#xff0c;更是完整。 sslTrus (RSA) OV CA可以选择&#xff1a;单域名、通配符…

生产级Redis Cluster部署(4.0.10版本)

生产级Redis Cluster部署 环境准备 主机名 IP地址 端口 描述 redis-master 192.168.1.51 7000 redis-master01 7001 redis-master02 7002 redis-master03 redis-slave 192.168.1.52 8000 redis-slave01 8001 redis-slave02 8002 redis-slave03 初始化…

代码随想录二刷day42 | 动态规划之背包问题 416. 分割等和子集

day42 416. 分割等和子集确定dp数组以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 416. 分割等和子集 题目链接 解题思路&#xff1a; 这是一维的背包问题 只有确定了如下四点&#xff0c;才能把01背包问题套到本题上来。 背包的体积为sum / 2背包要…

Java 实现快慢指针法返回链表的中间结点

一、思路 这里分为链表结点个数是 奇数 和 偶数 两种情况。 如果是奇数&#xff0c;中间结点只有一个&#xff0c;返回即可&#xff1b;如果是偶数&#xff0c;中间结点则有两个&#xff0c;这里要求返回第二个。 上述图片展示的就是奇数的情况&#xff0c;此时中间结点就是…

找不到“$libdir/postgis-X.X“问题解决方案

背景&#xff1a; 数据库从postgresql-11.9 升级到11.20版本&#xff0c;11.20版本采用了docker镜像 postgis/postgis:11-3.3 (截止20230703实际对应的版本为pg11.20postgis3.3) 升级版本&#xff0c;使用了原来的data&#xff0c;主要版本不变&#xff0c;次要版本升级&#…

文档管理系统是业迈向数字化办公的新时代

随着信息技术的不断发展&#xff0c;企业数字化办公已成为越来越多企业的选择。在数字化办公中&#xff0c;文档管理系统是一个非常重要的组成部分&#xff0c;可以帮助企业打破时空限制&#xff0c;提高工作效率和质量&#xff0c;推动企业向数字化办公的新时代迈进。 什么是…

力扣 39. 组合总和

题目来源&#xff1a;https://leetcode.cn/problems/combination-sum/description/ C题解&#xff1a; 递归法。递归前对数组进行有序排序&#xff0c;可方便后续剪枝操作。 递归函数参数&#xff1a;定义两个全局变量&#xff0c;二维数组result存放结果集&#xff0c;数组pa…

当使用POI打开Excel文件遇到out of memory时该如何处理?

摘要&#xff1a;本文由葡萄城技术团队于CSDN原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 当我们开发处理Excel文件时&#xff0c;Apache POI 是许多人首选的工具。但是&#xff…

ssh Permission denied, please try again

Permission denied, please try again 修改 vi /etc/sshd_config 最后重启配置或者重启板子&#xff0c;重新ssh连接