当前位置: 首页 > 编程日记 > 正文

开放平台鉴权以及OAuth2.0介绍

OAuth 2.0 协议

  • OAuth是一个开发标准,允许用户授权第三方网站或应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的内容。
  • OAuth 2.0不兼容1.0。

协议的参与者

  • RO (resource owner): 资源所有者,对资源具有授权能力的人。
  • RS (resource server): 资源服务器,它存储资源,并处理对资源的访问请求。
  • Client: 第三方应用,它获得RO的授权后便可以去访问RO的资源。
  • AS (authorization server): 授权服务器,它认证RO的身份,为RO提供授权审批流程,并最终颁发授权令牌(Access Token)。

授权方式

在开放授权中,第三方应用(Client)可能是一个Web站点,也可能是在浏览器中运行的一段JavaScript代码,还可能是安装在本地的一个应用程序。这些第三方应用都有各自的安全特性。对于Web站点来说,它与RO浏览器是分离的,它可以自己保存协议中的敏感数据,这些密钥可以不暴露给RO;对于JavaScript代码和本地安全的应用程序来说,它本来就运行在RO的浏览器中,RO是可以访问到Client在协议中的敏感数据。

OAuth2.0为了支持这些不同类型的第三方应用,提出了下面四种授权类型:

  1. 授权码 (Authorization Code Grant),适用于有server端的应用授权。
  2. 隐式授权 (Implicit Grant),适用于通过客户端访问的应用授权。
  3. 资源所有者密码凭证许可 (Resource Owner Password Credentials Grant),OAuth简化版,常用于移动应用认证,称为xAuth。
  4. 受保护资源的客户端授权 (Client Credentials Grant)。
流程Response Type(第一次请求)Grant Type(第二次请求)可带Refresh Token说明
授权码codeauthorization_code常规流程
Implicittoken-适用于纯JS程序
用户认证-password客户端高度可信,且授权码流程不方便实施
客户端-client_credentials客户端高度可信,拥有被操作资源(自用型),或操作非敏感资源

Authorization Code 授权

1. 授权场景

Authorization code 授权适用于PC,无线客户端等需要和第三方server进行交互的应用场景。使用Authorization code授权,第三方能够集中处理用户的授权请求和授权结果,适用于有server端的应用。

2. 授权流程

Authorization code授权模式分为两步,首先获取authorization code,然后用code获取acces token。

示意图:

复制代码
     +----------+| Resource ||   Owner  ||          |+----------+^|(B)+----|-----+          Client Identifier      +---------------+|         -+----(A)-- & Redirection URI ---->|               ||  User-   |                                 | Authorization ||  Agent  -+----(B)-- User authenticates --->|     Server    ||          |                                 |               ||         -+----(C)-- Authorization Code ---<|               |+-|----|---+                                 +---------------+|    |                                         ^      v(A)  (C)                                        |      ||    |                                         |      |^    v                                         |      |+---------+                                      |      ||         |>---(D)-- Authorization Code ---------'      ||  Client |          & Redirection URI                  ||         |                                             ||         |<---(E)----- Access Token -------------------'
     +---------+       (w/ Optional Refresh Token)
复制代码

交互图:

  
复制代码
  +--------+                                           +---------------+|        |--(A)------- Authorization Grant --------->|               ||        |                                           |               ||        |<-(B)----------- Access Token -------------|               ||        |               & Refresh Token             |               ||        |                                           |               ||        |                            +----------+   |               ||        |--(C)---- Access Token ---->|          |   |               ||        |                            |          |   |               ||        |<-(D)- Protected Resource --| Resource |   | Authorization || Client |                            |  Server  |   |     Server    ||        |--(E)---- Access Token ---->|          |   |               ||        |                            |          |   |               ||        |<-(F)- Invalid Token Error -|          |   |               ||        |                            +----------+   |               ||        |                                           |               ||        |--(G)----------- Refresh Token ----------->|               ||        |                                           |               ||        |<-(H)----------- Access Token -------------|               |+--------+           & Optional Refresh Token        +---------------+
复制代码

3. 过程详解

1、获取Authorization Code

请求参数

  • client_id 必须 分配给应用的appid
  • redirect_uri 必须 授权回调地址,必须和应用注册的地址一致
  • response_type 必须 授权类型,此值固定为“code”
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • scope 可选 授予权限范围
  • 其他参数

如果用户成功授权,则会跳转到指定的回调地址,并在redirect_uri地址后带上Authorization Code和原始的state值

2、通过Authorization Code获取Access Token

请求参数

  • client_id 必须 分配给应用的appid
  • grant_type 必须 授权类型,此值为:authorization_code
  • client_secret 必须 分配给应用的secret
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • redirect_uri 必须 与上面一步中传入的redirect_uri保持一致
  • code 必须 上一步返回的Authorization Code值(必须设定此code的有效时间)

返回参数

  • access_token 必须 授权令牌
  • expires_in 必须 该access_token的有效期
  • refresh_token 可选 在授权自动续期步骤中,获取新的Access_Token时需要提供的参数
  • 其他参数 可选

3、[可选] 权限自动续期,获取access_token

Access_token一般需要根据应用特性设定有效期,过期后需要用户重新授权或采用自动续期的方式。

请求参数

  • grant_type 必须 授权类型,在本步骤中,此值为“refresh_token”
  • client_id 必须 分配给应用的appid
  • refresh_token 必须 第二步返回的refresh_token
  • client_secret 必须 分配给应用的secret

如果授权成功,则会返回和步骤二同样的结果。

Implicit 授权

1. 授权场景

Implicit授权一般适用于没有server端的客户端应用,由客户端发起授权请求,保存和处理access_token,但有些应用(如web应用等)为了提高用户体验,简化授权过程,也会常采用Implicit授权方式(注意,这种授权方式没有返回refresh_token。)

2. 授权流程

示意图:

复制代码
     +----------+| Resource ||  Owner   ||          |+----------+^|(B)+----|-----+          Client Identifier     +---------------+|         -+----(A)-- & Redirection URI --->|               ||  User-   |                                | Authorization ||  Agent  -|----(B)-- User authenticates -->|     Server    ||          |                                |               ||          |<---(C)--- Redirection URI ----<|               ||          |          with Access Token     +---------------+|          |            in Fragment|          |                                +---------------+|          |----(D)--- Redirection URI ---->|   Web-Hosted  ||          |          without Fragment      |     Client    ||          |                                |    Resource   ||     (F)  |<---(E)------- Script ---------<|               ||          |                                +---------------++-|--------+|    |(A)  (G) Access Token|    |^    v+---------+|         ||  Client ||         |+---------+Note: The lines illustrating steps (A) and (B) are broken into twoparts as they pass through the user-agent.
复制代码

交互图:

 
复制代码
     +----------+| Resource ||  Owner   ||          |+----------+v|    Resource Owner(A) Password Credentials|v+---------+                                  +---------------+|         |>--(B)---- Resource Owner ------->|               ||         |         Password Credentials     | Authorization || Client  |                                  |     Server    ||         |<--(C)---- Access Token ---------<|               ||         |    (w/ Optional Refresh Token)   |               |+---------+                                  +---------------+
复制代码

交互图:

3. 过程详解

请求参数

  • response_type 必须 授权类型,在本步骤中,此值为“token”
  • client_id 必须 分配给应用的appid
  • redirect_uri 必须 授权回调地址,必须和应用注册的地址一致
  • scope 可选 授予权限范围
  • state 必须 client端的状态值。用于第三方应用防止CSRF攻击,成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
  • 其他参数 可选

如果成功授权,则会跳转到redirect_uri指定的回调地址,并带上access_token、expires_in、state以及与应用相关的参数。注意,这种授权方式没有返回refresh_token。

Resource Owner Password Credentials

该授权方式获取access token一般只有一步,类似如下GET/POST请求:https://open.xxx.com/oauth2/access_token?client_id=xxxx&client_secret=xxxxx&grant_type=password&username=xxx&password=xxx

OAuth2.0新特性

  • 服务器角色区分:授权服务器和资源服务器
  • 区别不同的用户类型、授权场景和授权流程
  • 将token分为频繁传输使用但是有效时长较短的Access Token和用于更新Access Token的Refresh Token
  • 定义多种token,降低资源请求的构造难度
  • 授权过程不签名,可根据需要采用HTTPS加密传输、验证客户端密钥(通过签名)、客户端注册时预先指定callback地址等手段。
  • 明确引入客户端注册流程:确定Client Type、callback URL以及其它信息
  • 引入可选的state参数,帮助客户端防范CSRF和管理状态
  • 引入scope参数,可以进行授权范围控制
  • token type等可被扩展: bearer(HTTPS), mac(HTTP+sign), etc.

淘宝的OAuth2.0安全控制

  • 只支持HTTPS(bears),不支持签名(签名是走以前老的授权方式)
  • 授权过程指定的callback URL必须与注册的callback URL在同一个域名,或者为um:ietf:wg:oauth:2.0:oob(表示只显示授权码,不回调callback URL)
  • 接口分不同级别(R1, R2, W1, W2),同一Token对不同级别接口有不同的有效期
  • 接口权限划分(item, promotion, user, etc.)

说明 为何引入authorization_code?

协议设计中,为什么要使用authorization_code来交换access_token?这是读者容易想到的一个问题。也就是说,在协议的第3步,为什么不直接将access_token通过重定向方式返回给Client呢?比如:

HTTP/1.1 302 Location: https://www.facebook.com/?access_token=ya29.AHES6ZSXVKYTW2VAGZtnMjD&token_type=Bearer&expires_in=3600

如果直接返回access_token,协议将变得更加简洁,而且少一次Client与AS之间的交互,性能也更优。那为何不这么设计呢?协议文档[1]中并没有给出这样设计的理由,但也不难分析:(1) 浏览器的redirect_uri是一个不安全信道,此方式不适合于传递敏感数据(如access_token)。因为uri可能通过HTTP referrer被传递给其它恶意站点,也可能存在于浏览器cacher或log文件中,这就给攻击者盗取access_token带来了很多机会。另外,此协议也不应该假设RO用户代理的行为是可信赖的,因为RO的浏览器可能早已被攻击者植入了跨站脚本用来监听access_token。因此,access_token通过RO的用户代理传递给Client,会显著扩大access_token被泄露的风险。 但authorization_code可以通过redirect_uri方式来传递,是因为authorization_code并不像access_token一样敏感。即使authorization_code被泄露,攻击者也无法直接拿到access_token,因为拿authorization_code去交换access_token是需要验证Client的真实身份。也就是说,除了Client之外,其他人拿authorization_code是没有用的。 此外,access_token应该只颁发给Client使用,其他任何主体(包括RO)都不应该获取access_token。协议的设计应能保证Client是唯一有能力获取access_token的主体。引入authorization_code之后,便可以保证Client是access_token的唯一持有人。当然,Client也是唯一的有义务需要保护access_token不被泄露。 (2) 引入authorization_code还会带来如下的好处。由于协议需要验证Client的身份,如果不引入authorization_code,这个Client的身份认证只能通过第1步的redirect_uri来传递。同样由于redirect_uri是一个不安全信道,这就额外要求Client必须使用数字签名技术来进行身份认证,而不能用简单的密码或口令认证方式。引入authorization_code之后,AS可以直接对Client进行身份认证(见步骤4和5),而且可以支持任意的Client认证方式(比如,简单地直接将Client端密钥发送给AS)。 在我们理解了上述安全性考虑之后,读者也许会有豁然开朗的感觉,懂得了引入authorization_code的妙处。那么,是不是一定要引入authorization_code才能解决这些安全问题呢?当然不是。笔者将会在另一篇博文给出一个直接返回access_token的扩展授权类型解决方案,它在满足相同安全性的条件下,使协议更简洁,交互次数更少。

********转载:https://www.cnblogs.com/duanxz/p/4369738.html

转载于:https://www.cnblogs.com/linybo/p/10053103.html

相关文章:

1044 Shopping in Mars

这题我写了两个二分函数。 BS借用的模板是找到第一个大于等于总价的商品下标&#xff0c;然后返回的是钻石价值和减去商品总价&#xff0c;通过遍历来得到最小的差值&#xff0c;注意遍历的最后一个数字的时候可能会返回负值&#xff0c;所以只有当返回值大于等于0才可以用来竞…

nodeJS之eventproxy源码解读

1.源码缩影 !(function (name, definition) { var hasDefine typeof define function, //检查上下文环境是否为AMD或CMD hasExports typeof module ! undefined && module.exports; //检查上下文环境是否为Node if (hasDefine) { define(definition); //AMD环境或CM…

解决phpmyadmin3.4空密码登录被禁止登陆的方法

很多时候我们在本机测试时会将root用户密码设置为空。因为我把php升级到了5.3.1&#xff0c;以前的phpmyadmin版本不能用了&#xff0c;就升级到phpMyAdmin 3.2.4版的时候&#xff0c;会遇到无法以空密码登录root用户的情况。怎么解决呢? 请参照如下步骤&#xff1a; 1、打开程…

CentOS安装新版RabbitMQ解决Erlang 19.3版本依赖

2019独角兽企业重金招聘Python工程师标准>>> 通过yum等软件仓库都可以直接安装RabbitMQ&#xff0c;但版本一般都较为保守。 RabbitMQ官网提供了新版的rpm包&#xff08;http://www.rabbitmq.com/download.html&#xff09;&#xff0c;但是安装的时候会提示需要erl…

1048 Find Coins(二分法解法)

非常基础的二分法-寻找序列中是否存在某一条件的元素 的应用 AC代码 #include<cstdio> #include<iostream> #include<set> #include<vector> #include<map> #include<algorithm>using namespace std;const int SUP 100000000; const in…

关于chrome等浏览器不支持showModalDialog的解决方案

目前&#xff0c;新版本的chrome和opera、Firefox等浏览器已经不支持showModalDialog方法。 如果是没有接收返回值的&#xff0c;可以直接将window.showModalDialog改为window.open。 需要接收返回值的情况&#xff1a; 父页面设置&#xff1a; var uIdName; function chooseus…

Flex Javascript 交互实现代码

关键字&#xff1a;ExternalInterface所用类库&#xff1a;SWFObject/*** Flex调用Javascript函数* params functionName:String Javascript函数名称* params ...params Javascript函数参数* return 返回Javascript函数的return内容**/ExternalInterface.call(functionName:Str…

C#反射使用时注意BindingFlags的用法(转载)

最近刚刚开始用反射做项目&#xff0c;遇到一个小的知识点&#xff0c;记录一下。 c#反射查找方法时&#xff0c;默认只能查到public方法。如果想要查找private方法&#xff0c;需要设定BindingFlags. 即&#xff1a; BindingFlags.Public|BindingFlags.Instance 默认…

1126 Eulerian Path

主要考英语或者数学基础。 一幅连通图的奇点个数为0或2时才能够被一笔画。 连通图的判断用DFS来计数。 连通图0个奇点&#xff1a;Eulerian 连通图2个奇点&#xff1a;semi-Eulerian 非连通图/连通图其他数量的奇点&#xff1a;non-Eulerian AC代码 #include<cstdio&…

各种小的 dp (精)

Q~ 抛一枚硬币 n 次&#xff0c;每次可能是正面或者反面向上&#xff0c;求没有连续超过 k 次硬币向上的方案数 A &#xff1a; dp[ i ] 表示到 i 位置的方案数&#xff0c; 1 . 当 i < k 时&#xff0c; dp[i] dp[i-1]*2 2 . 当 i k 时&#xff0c; dp[i] dp[i-1]*2 - 1…

写给还在大学的兄弟姐妹

看到软件专业毕业生之一个月攻略 这篇文章之后&#xff0c;忽然想起了自己两个多月前找工作时的写的一篇文章&#xff0c;便拿出来与大家分享。这仅是个人的一些看法&#xff0c;不正确之处还请各位指出&#xff0c;有砖尽管拍。 基础很重要 许多企业招聘&#xff0c;要求大学…

grunt学习

1、http://javascript.ruanyifeng.com/tool/grunt.html Grunt&#xff1a;任务自动管理工具 2、转载于:https://www.cnblogs.com/king-bj/p/4322794.html

IP地址和MAC地址

MAC地址又称硬件地址&#xff0c;是MAC帧的头部&#xff0c;在数据链路层只能看见MAC地址。 IP地址是逻辑地址&#xff0c;是IP数据报的头部&#xff0c;路由器根据IP地址进行路由选择。 IP地址为4个字节32位&#xff0c;编制经历了3个历史阶段。 MAC地址为6个字节48位。

ie9下console不兼容的问题

最近在调整项目在ie9下的展示问题&#xff0c;发现在ie9下&#xff0c;js文件不执行&#xff0c;打开控制台才执行&#xff0c;原因是ie9不支持console&#xff0c;以下给出两种解决方案&#xff1a;1. 在webpack.prod.conf.js 中添加并修改js插件配置项&#xff08;我用的是we…

[转载] linux、Solaris下xdmcp远程桌面服务

原文链接 http://youlvconglin.blog.163.com/blog/static/52320420106243857254/ 使用图形界面远程登录linux和Solaris&#xff0c;首先要在服务端开启xdmcp服务&#xff0c;windows下使用xmanager连接 Ubuntu下则使用下默认也安装了该客户端&#xff0c;一次打开[应用程序]-[…

3.2.4 控制图层显示的范围

为了是地图更加简洁 和 减小地图负载 &#xff0c;达到分级显示某些图层的效果&#xff0c;应该为每一个图层设置 合理的 可见比例尺范围。1 begin2 3 aeMapMain.Layer[2].MaximumScale :500000;//最大可见比例尺 分母4 aeMapMain.Layer[2].MinimumScale :1000000;//最小可见比…

1103 Integer Factorization 需再做

本题是典型的DFS剪枝 我对DFS有了更深的认识&#xff1a;整个过程就是一片森林(根节点不唯一)的生长&#xff0c;到了界限就得到结果并返回或者得不到结果也返回&#xff0c;DFS的参数存放的是所有需要积累的变量。 提示&#xff1a; 1. 最外层的while或者for可以看成是一个…

POJ1001--Exponentiation(幂计算)翻译

Exponentiation幂计算Time Limit: 500MSMemory Limit: 10000KTotal Submissions: 141868Accepted: 34673 Description 描述 Problems involving the computation of exact values of very large magnitude and precision are common. 高精度、大数值的计算问题是很常见的&…

datatable无法设置横向滚动条(设置无效)

datatable设置横向滚动条无效 js如下&#xff1a; 页面如下&#xff1a; 设置 scrollx 属性为true时&#xff0c;还需在 table 添加 style"white-space: nowrap; "最终效果&#xff1a; 转载于:https://www.cnblogs.com/renzp/p/10069594.html

水晶报表导出数据并实现打印

要在里一个页面上进行操作 ReportDocument rdocument new ReportDocument(); //公用打印方法 ExportCrystalL ExCrystal new ExportCrystalL(); User u new User(); #region 加载页面 protected void Page_Load(object sender, EventArgs e) { if (!IsPostB…

1130 Infix Expression

考察&#xff1a;DFS进行中序遍历。 注意&#xff1a;给除了根节点以外的父节点加左右括号。 AC代码 #include<cstdio> #include<iostream> #include<set> #include<vector> #include<map> #include<algorithm> #include<cmath> …

学习笔记之vue根据权限动态添加路由

路由守卫判断 router.beforeEach((to, from, next) > {if (to.path /login) {sessionStorage.removeItem(user);}if (!user && to.path ! /login&&location.search ! ?validate) {next({ path: /login })} else {next()} }) 复制代码 点击登陆后&#xff…

javascript重置(base层)(。。。。不完整)

1、nextSibling浏览器兼容问题 <ul><li id"item1"></li><li id"item2"></li><li id"item3"></li> </ul> var item1document.getElementById("item1"); alert(item1.nextSibling.id);…

java myeclipse jar 导出问题

1.工程 jdk要和实际jdk最好一个版本;2.有外部导入的jar,导出时应用manifest&#xff0c;设置外部引用JAR。例如&#xff1a;Manifest-Version: 1.0 Sealed: true Class-Path: lib/log4j-1.2.8.jar lib/xercesImpl.jar Main-Class: com.unimoco.mmsplatform.handler.MMSMOCenter…

漫谈回溯(未完待续)

将不使用优化算法、直接用朴素算法来解决问题的做法称为暴力法。 回溯是带优化的穷举。 回溯是具有界限函数的深度优先搜索。

sendStickyBroadcast和sendStickyOrderedBroadcast

sendStickyBroadcast和sendStickyOrderedBroadcast - 牛仔的移动开发博客 - 博客频道 - CSDN.NET sendStickyBroadcast和sendStickyOrderedBroadcast发出的广播会一直滞留&#xff08;等待&#xff09;&#xff0c;以便有人注册这则广播消息后能尽快的收到这条广播。其他功能与…

固定资产打印条码标签应用方案

条码在固定资产管理中的应用方案&#xff1a; 应用客户案例&#xff1a; 河南省交通规划勘察设计院 黄河水文勘察测绘局 以实物管理为基础&#xff0c;以条码技术的应用为特点。通过先进的条码技术对固定资产实物从购置、领用、转移、盘点、清理到报废等方面进行全方位准确监管…

有关于诚信:唐骏学历门

提高造假的成本 - 南桥的博客 唐骏的学历门曝光后&#xff0c;我回想起过去的一件往事来。我读博士的时候&#xff0c;有人找我合作&#xff0c;在其介绍材料里写“博士”&#xff0c;我赶紧写信纠正&#xff0c;说自己是“博士生”&#xff08;doctoral student)&#xff0c;而…

1115 Counting Nodes in a BST

我的DFS void DFS(Node* root){if(rootNULL)return;if(root->lchild){root->lchild->layer root->layer1;cnt[root->lchild->layer] ;maxLayer max(maxLayer,root->lchild->layer);DFS(root->lchild);}if(root->rchild){root->rchild->…

必会重构技巧:使用多态替换条件

使用多态替换条件&#xff1a;指在进行类型检查和执行某些类型操作时&#xff0c;最好将算法封装在类中&#xff0c;并且使用多态来对代码中的调用进行抽象 举例理解&#xff1a;看定义可能比较迷糊&#xff0c;其实说的简单一点&#xff0c;对于使用分支语句并且分支条件是和…