一、什么是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. Java权威编码规范

    一.编程规约 (一) 命名规约 1. [强制] 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例: _nam / __name / $Object / name_  / ...

  2. 聊一聊python的单例模式

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. PKU 1226 Substrings(字符串匹配+暴搜KMP模板)

    原题大意:原题链接 给出n个字符串,找出一个最长的串s,使s或者s的反转字符串(只要其中一个符合就行)同时满足是这n个串的子串. 对于样例,第一组ABCD   BCDFF  BRCD最长的串就是CD; ...

  4. Unity本地数据存储---Sqlite和JSON

    2014-05-04更新 SqliteDatabase.cs这个文件的初始方法有问题,具体是如果指定URL已经存在了DB文件,就不会重新覆盖DB文件. 这导致我们修改之后的DB文件无法产生效果. 本人 ...

  5. linux 注销其他用户

    本文主要参考:http://ysz520020.blog.163.com/blog/static/352595722011969264745 linux kill掉其他的登录用户 : 方法一: 使用 ...

  6. dubbo-admin 监控中心 部署

    dubbo-admin部署 下载: GitHub:https://github.com/search?q=dubbo-admin 百度网盘: 链接:https://pan.baidu.com/s/1v ...

  7. 谷歌技术"三宝"之BigTable(转)

    原文地址:   http://blog.csdn.net/opennaive/article/details/7532589 2006年的OSDI有两篇google的论文,分别是BigTable和Ch ...

  8. 解决Linux 下server和client 通过TCP通讯:accept成功接收却报错的问题

    今天在写简单的TCP通讯例子的时候,遇到了一个问题:server 和client能够连接成功,并且client也能够正常发送,但server就是接收不到,在网上搜索一番后,终于解决了问题.在这里整理如 ...

  9. 学号20145322 《Java程序设计》第一周学习总结

    学号20145322 <Java程序设计>第一周学习总结 教材学习内容总结 Java诞生于Sun公司,于1998年12月4日发布J2SE,约以两年为一周期推出重大版本更新. 2010年Or ...

  10. C++第二次上机5-5

    建立一个复数类Complex,实数和虚数是其私有数据成员: 建立复数类的无参和参数化构造函数: 建立一个 *(乘号)的运算符重载,以便于对两个复数直接进行乘法运算: 建立输出函数void displa ...