一、什么是OAuth

二、什么场景下会用到OAuth授权

三、OAuth 2.0中的4个成员

四、OAuth 2.0授权流程

五、OAuth 2.0授权模式

1、    authorization code(授权码模式)

2、    implicit(简化模式)

3、    resource owner password credentials(密码模式)

4、    client credentials(客户端模式)

六、小结

一、什么是OAuth

  所谓的OAuth(Open Authorization)本质上就是一张开放的协议,OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。 与以往的授权方式不同该授权不会使第三方触及到用户的账户信息,即第三方无需使用用户名密码就可以申请该用户资源的授权,因此OAuth是安全的。这是来自百度百科对OAuth的解释。

  而OAuth2.0呢,故名思义就是OAuth的下一个版本,同时它也是授权领域的行业标准协议,OAuth2.0不支持向后兼容,即不支持OAuth1.0,彻底废止了OAuth1.0协议,OAuth2.0致力于使客户端开发者通过更简单的流程为Web应用、桌面应用以及手机客户端等设备进行授权。2012年10月,OAuth2.0协议正式发布为RFC6749。目前各大开放平台,如腾讯、新浪、百度等等也都是以OAuth2.0协议作为支撑。

二、什么场景下会用到OAuth授权

 目前我们大多数的应用场景,也是我们最熟悉的使用环境就是使用第三方登录,如:微博,QQ,微信,豆瓣等社交平台登录,互联网发展到今天,我们也都习惯了这种登录方式,最大的好处就是便捷,简化了我们一系列的注册流程,还有一大堆帐号密码记不住的困扰,当你碰到一个不支持第三方登录的网站或者应用的时候,第一感觉就是厌恶,一顿喷。人永远离不开社交,所以通过社交平台去登录其他的平台,无疑是最受大家欢迎的方式了。  

  就拿CSDN为例,CSDN是支持第三方平台登录的,截图如下:

若用户想使用QQ登录,那么在传统的认证模式中,客户端(CSDN)请求访问服务器上受限的资源(QQ),需要通过资源所有者(用户的QQ账户)的凭证在服务器上进行认证。为了支持第三方应用程序(对于QQ来说,CSDN是第三方应用程序,是CSDN去请求访问QQ的资源)访问受限资源,资源所有者需要向第三方应用共享其凭证(如用户QQ的帐号和密码)。那这样就会造成以下几个问题:

  • 第三方应用(CSDN)为了以后继续使用,那么会存储资源所有者的凭证,如密码;
  • 服务端需要支持密码认证,尽管密码认证不安全;
  • 第三方应用若想访问资源所有者的其他资源,资源所有者无法对其进行限制;
  • 资源所有者无法收回第三方的访问权限,除非用户主动修改密码;
  • 如果此时第三方的数据泄漏,那也会导致资源所有者其他数据的泄漏,造成重大损失。

    若此时,CSDN知道了用户的QQ密码,那CSDN可以任意去访问该用户的所有信息,而QQ无法去限制它的访问,这不管是对QQ还是用户本身都会是一件可怕的事,作为使用者,你永远都无法知道应用都干了些什么。由此OAuth2.0的出现,就是为了解决这样的问题。

三、OAuth 2.0中的4个成员

在OAuth2.0中有4个成员,Resource Owner、Resource Server、Client、Authorization Server,如图所示:

在上面4个成员中,授权服务器可能与资源服务器在同一台服务器。

四、OAuth 2.0授权流程

流程如下,图片来自RFC6749:

流程解析:

  1. 用户打开客户端,客户端要求向资源所有者(即用户)给予授权;
  2. 用户同意授权;
  3. 客户端得知用户同意授权后,向授权服务器获取授权;
  4. 授权服务器给予客户端授权,并将授权码(Access Token);
  5. 客户端携带授权码去请求资源服务器;
  6. 资源服务器将受限的资源开放给客户端。

五、OAuth 2.0授权模式

授权许可是表示客户用来获取访问令牌的资源所有者授权的凭证。此规范协议规定了4种授权类型:

  • authorization code(授权码模式)
  • implicit(简化模式)
  • resource owner password credentials(密码模式)
  • client credentials(客户端模式)

下面详细说明各种授权模式的具体流程:

  1、authorization code(授权码模式)

授权代码授权类型用于获取访问令牌和刷新令牌,并针对机密客户端进行优化。它是一个基于重定向的流程,因此客户端必须能够与资源所有者的用户代理(通常是Web浏览器)并且能够从授权服务器接收传入请求(通过重定向)。授权码模式是功能最完整、流程最严密的授权模式,它的特点就是通过客户端的后台服务器,与"服务提供商"的授权服务器进行互动。授权流程如下:

流程解析:

  1. 客户端通过用户代理,重定向请求授权服务器,所需参数:客户端标识及重定向URL;
  2. 用户选择是否给予客户端授权;
  3. 授权服务器给予客户端一个认证授权码,并跳转到指定的URI;
  4. 客户端使用该授权码,重定向到授权服务器,获取令牌;
  5. 授权服务器校验该授权码以及重定向的URI后,向客户端发送令牌或者更新令牌。

以上均个人解释,简化了RFC6749官方文档说明,大致意思是一样的。注意的一点是,在用户同意授权后,授权服务器并未直接将令牌发送给客户端,而是先向客户端发送了一个授权码,authorization code,然后再携带该授权码,再一次请求授权服务器,校验无误后,再发送令牌(access token),这一步是在后台自动完成的,这样也使OAuth授权更加安全。

在该授权流程中,我们所需的几个参数,官方文档中要求指定的参数如下:

  • response_type 必选项 表示的是要求指定的授权类型,此处必须设置为:code
  • client_id 必选项 客户端的唯一标识
  • redirect_uri 可选项 重定向的URI
  • scope 可选项 授权的管道
  • state 建议项 表示客户端状态,授权服务器会将该状态原值返回

看完该流程以及所需的参数后,我们结合实际情况,还是上面提到的例子,以CSDN使用QQ登录为例,看一下该过程:

(A步骤)点击QQ登录,跳转到QQ帐号安全登录界面,即腾讯的互联平台,我们可以直接拿到此时CSDN要请求的地址:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&

response_type=code&

client_id=100270989&

redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&

state=test

这样我们可以很清楚的看到在上面的URL中,发起了一个get请求,他的授权类型为code 授权码模式,以及client_id,redirect_uri,state等信息,而此时页面也跳转到了用户代理的页面,让用户去决定是否要同意授权 :

(C步骤)当用户输入用户名密码后点击授权并登录,服务器会先验证你输入的是否正确,如果正确,页面就会跳转到redirect_uri的地址中,而在这个过程中发生的变化是这样的,我们继续查看这时的URL地址:

https://passport.csdn.net/account/login?oauth_provider=QQProvider&

code=D185F3ED93E4F1B3C5F557E6112C7A9B&

state=test

(D步骤)我们可以看到授权并登录后它重定向到了我们指定的地址,而且还给予了一个code授权码,另外state状态还是在请求登录时的状态,在下一个步骤中,是客户端向授权服务器申请令牌,包含以下参数:

  • grant_type 表示授权模式,此处固定为authorization_code,必选
  • code 表示上一步获取到的授权码,必选
  • redirect_uri 表示重定向URI,必选
  • client_id 表示客户端ID,必选

在使用腾讯开放平台时,它会要求有一个client_secrect,是对应你客户端ID的一个私钥,它也是在客户端注册时产生的,所以在使用QQ登录获取令牌时,也必须指定该选项:client_secret,具体的可以看腾讯的开发文档。那么实际上申请令牌的这个过程我们是看不到的,返回authorization code 后,我们会看到我们的客户端此时已经登录成功了。例如:

POST /token HTTP/1.1

Host: graph.qq.com/oauth2.0/token

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA

&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&client_secret=fdhsjfdsj32jjfhjdk

(E步骤)若以上返回成功,那么在E步骤中会返回如下信息:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",

"example_parameter":"example_value"

}

里面包含了我们所需要的令牌access token以及有效期等信息。实际上在我们实际应用过程中,我们不止是到这里就结束了,我们会使用access token令牌再去请求资源服务器,获取可以被调用的资源,以及一些其他的操作。

  2、implicit(简化模式)

简化模式用于获取访问令牌(但它不支持令牌的刷新),并对运行特定重定向URI的公共客户端进行优化,而这一些列操作通常会使用脚本语言在浏览器中完成,令牌对访问者是可见的,且客户端也不需要验证。具体流程如下:

步骤解析:

  1. 客户端携带客户端标识以及重定向URI到授权服务器;
  2. 用户确认是否要授权给客户端;
  3. 授权服务器得到许可后,跳转到指定的重定向地址,并将令牌也包含在了里面;
  4. 客户端不携带上次获取到的包含令牌的片段,去请求资源服务器;
  5. 资源服务器会向浏览器返回一个脚本;
  6. 浏览器会根据上一步返回的脚本,去提取在C步骤中获取到的令牌;
  7. 浏览器将令牌推送给客户端。

(A步骤)中需要用到的参数,注意在这里要使用"application/x-www-form-urlencoded"格式:

  • response_type 必选项,此值必须为"token"
  • client_id 必选项
  • redirect_uri 可选项
  • scope 可选项
  • state 建议选项

    例如:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
        &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
    Host: server.example.com

(C步骤)中返回的参数包含:

  • access_token 必选项
  • token_type 必选项
  • expires_in 建议选项
  • scope 可选项
  • state 必选项

    例如:

HTTP/1.1 302 Found
     Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
               &state=xyz&token_type=example&expires_in=3600

  3、resource owner password credentials(密码模式)

密码模式适合建立在客户端与资源所有者具有信任关系的情况下,例如它是一个设备的操作系统或者具有很高权限的应用。这种模式用户要向客户端提供自己的用户名密码,从而达到向服务提供商索取授权。授权服务器在启动此类型时,要特别小心,只有在其他的授权方式不被允许的情况下才可以使用这种授权模式。流程如下:

  1. 客户端要求使用资源所有者的密码;
  2. 资源所有者给予用户名密码后,客户端向授权服务器发起申请令牌的请求;
  3. 授权服务器将令牌发放给客户端。

步骤解析:

(B步骤)所需参数:

  • grant_type 必选项 此值必须为"password"
  • username 必选项 用户名
  • password 必选项 密码
  • scope 可选项

例如:

POST /token HTTP/1.1

Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

(C步骤)发放令牌:

HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache
     {
       "access_token":"2YotnFZFEjr1zCsicMWpAA",
       "token_type":"example",
       "expires_in":3600,
       "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
       "example_parameter":"example_value"
     }

  4、client credentials(客户端模式)

客户端模式是4种模式中最简单的一种模式。客户端可以使用客户端凭据请求访问令牌(或者其他支持的认证方式),在这种模式中,客户端占据主导地位,它不需要用户的同意,可以直接向授权服务器索取令牌,严格来说,该模式并不存在授权的问题,流程如下:

  1. 客户端向授权服务器发起请求索要令牌;
  2. 授权服务器将令牌发放给客户端。

步骤解析:

(A步骤)中所需的参数::

  • grant_type 必选项 此值必须为client_crendentials
  • scope 可选项

例如:

POST /token HTTP/1.1

Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

(B步骤)授权服务器返回结果:

HTTP/1.1 200 OK

Content-Type: application/json;charset=UTF-8

Cache-Control: no-store

Pragma: no-cache

{

"access_token":"2YotnFZFEjr1zCsicMWpAA",

"token_type":"example",

"expires_in":3600,

"example_parameter":"example_value"

}

六、小结

    以以上内容简要介绍了关于OAuth授权的一些基础知识以及各种授权模式的具体流程。在后面的文章中,会结合本篇内容,陆续讲解如何在.net core中借助IdentityServer4 使用 OAuth 2.0授权。

扫描二维码关注我的公众号,共同学习,共同进步!

理解OAuth 2.0授权的更多相关文章

  1. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】

    github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...

  2. [转发] 理解 oauth 2.0

    原文: http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html oauth 的各种编程语言实现: http://oauth.net/2/ 理解OAu ...

  3. 简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析

    简单理解 OAuth 2.0 及资料收集,IdentityServer4 部分源码解析 虽然经常用 OAuth 2.0,但是原理却不曾了解,印象里觉得很简单,请求跳来跳去,今天看完相关介绍,就来捋一捋 ...

  4. 理解 OAuth 2.0

    理解OAuth 2.0 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html 一.简介 OAuth是一个关于授权(authorization)的开 ...

  5. 转 OAuth 2.0授权协议详解

    http://www.jb51.net/article/54948.htm 作者:阮一峰 字体:[增加 减小] 类型:转载 时间:2014-09-10我要评论 这篇文章主要介绍了OAuth 2.0授权 ...

  6. 理解OAuth 2.0 - 阮一峰的网络日志

    原文:理解OAuth 2.0 - 阮一峰的网络日志 理解OAuth 2.0 作者: 阮一峰 日期: 2014年5月12日 OAuth是一个关于授权(authorization)的开放网络标准,在全世界 ...

  7. OAuth 2.0 授权认证详解

    一.认识 OAuth 2.0 1.1 OAuth 2.0 应用场景 OAuth 2.0 标准目前被广泛应用在第三方登录场景中,以下是虚拟出来的角色,阐述 OAuth2 能帮我们干什么,引用阮一峰这篇理 ...

  8. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【密码模式(Resource Owner Password Credentials)】

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码.客户端使用这些信息,向"服务商提供商"索要授权 ...

  9. React + Node 单页应用「二」OAuth 2.0 授权认证 & GitHub 授权实践

    关于项目 项目地址 预览地址 记录最近做的一个 demo,前端使用 React,用 React Router 实现前端路由,Koa 2 搭建 API Server, 最后通过 Nginx 做请求转发. ...

随机推荐

  1. 001-linux scp文件拷贝

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  2. 013-HQL中级3-Hive四种数据导入方式介绍

    Hive的几种常见的数据导入方式这里介绍四种:(1).从本地文件系统中导入数据到Hive表:(2).从HDFS上导入数据到Hive表:(3).从别的表中查询出相应的数据并导入到Hive表中:(4).在 ...

  3. CCF 201312-4 有趣的数[dp][难]

    问题描述 试题编号: 201312-4 试题名称: 有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, ...

  4. C++实现去掉string字符串前后的空白字符

    C++标准库提供的字符串类string没有提供类似CString中Trim方法,该方法功能为去除字符串前后的空白字符.利用string自身一些方法可以很容易实现该功能. 如下: void Trim(s ...

  5. flask—信号(blinker)

    Flask框架中的信号基于blinker,主要是让开发者在flask请求过程中定制一些用户行为. 安装blinker pip3 install blinker 1.内置信号 request_start ...

  6. Vue组件的定义方式

    1.使用template标签定义组件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  7. 前端神器ws激活步骤

    第一步:下载破解文件 也可以直接去我的github仓库中下载 第二步骤:操作bin目录的文件bin目录window下和mac下大致相同,故而不在单独说window a.将补丁复制到webstorm安装 ...

  8. [转]linux内核分析笔记----内存管理

    转自:http://blog.csdn.net/Baiduluckyboy/article/details/9667933 内存管理,不用多说,言简意赅.在内核里分配内存还真不是件容易的事情,根本上是 ...

  9. Camera帧率和AE的关系

    1.camera首先是通过曝光的pixel加上dummy pixel以及曝光的line加上dummy line来决定一帧的曝光时间,这一帧曝光时间的倒数就是帧率,这个没有错吧,但是看代码时候看到pre ...

  10. 找不到resources下的文件

    今天发现一个很坑的问题,浪费了很长的时间排查问题,特此记录下.目录结构如下图所示: 结果加载文件的时候,一直报错: 找不到resource文件夹下的 conf/mybatis/logDb/ 路径下的文 ...