zoukankan      html  css  js  c++  java
  • OAuth 2.0系列(一)--- OAuth2授权流程

    最近在看《OAuth 2.0实战》(作者:贾斯廷.里彻和安东尼奥.桑索)这本书,打算边学边以博客的形式进行总结,博客命名为OAuth2系列($number),其中的number为博客顺序。

    一、什么是OAuth 2.0

     OAuth 2.0是一个授权协议,它允许软件应用代表(而不是充当)资源拥有者去访问资源拥有者的资源,应用向资源拥有者请求授权,然后取得令牌(token),并用它来访问资源。

    以上是文章中对OAuth 2.0的解释,仔细剖析,可以得到以下几个关键的信息:

    • 软件应用 
    • 代表资源拥有者 
    • 访问资源拥有者的资源
    • 应用向资源拥有者请求授权

    其实一句简单的话中包含了OAuth中最关键的三种角色:客户端(应用)、资源拥有者、受保护的资源。而OAuth设计的目的就是:

    让用户通过OAuth将他们在受保护资源上的部分权限委托给客户端应用,使客户端应用代表他们执行操作

    这个委托的过程就是授权的过程,所以自然而然地引入了第四种角色:授权服务器

    二、OAuth中的四种角色

    举一个例子:假设你是京东的一个程序员,最近手里负责了五六个项目,有点顾不过来,于是你招了一个外包同学,希望委托他帮你负责其中的三个项目,你要求他今天入职并将那三个项目的代码pull下来熟悉熟悉,从他入职到拉下代码需要以下几个步骤:

    第一步:他告诉你他到公司楼下了,进京东大厦需要你来证明;

    第二步:你需要在公司内部的办公软件上申请一个访客码给他,首先你用自己的erp账号登录了办公软件,申请成功并发送了一个访客码给外包同学;

    第三步:外包同学拿着访客码进入京东大厦,办理了入职流程,同时人事小姐姐给他在内部办公软件上开通了一个erp账号;

    第四步:他找到你,并用自己的erp账号登录了git地址,从git上clone了你给他开通权限的三个项目的代码;

    以上这个例子就发生的身边,仔细想来其实跟OAuth 2.0的授权流程很相似,其中包含了OAuth中最重要的四种角色:客户端、资源拥有者、授权服务器、受保护的资源

    1、客户端

     客户端是代表资源拥有者访问受保护资源的软件,即上面例子中的外包同学,你委托他帮你负责三个项目。

    2、资源拥有者

    资源拥有者是有权将访问权限授权给客户端的主体,即上面例子中的你,你拥有6个项目代码的读写权限。

    3、受保护的资源

    受保护的资源是能够通过http服务器进行访问,访问时需要OAuth下发的令牌(token),即上面例子中的代码库;

    4、授权服务器

    授权服务器是一个HTTP服务器,它在OAuth系统中充当中央组件。授权服务器对资源拥有者和客户端进行身份认证,让资源拥有者向客户端授权、为客户端颁发令牌,即上面例子中的公司办公软件。以上流程可以用下面的图来表示:

    上图诠释了外包同学入职并clone你给他开通权限的代码的整个过程,图中的数字每一步数字代表的含义如下:

    1. 你委托外包同学负责你的三个项目
    2. 外包同学告诉你进京东大厦需要你的证明,于是你需要去申请一个访客码
    3. 你用自己的erp账号登录内部办公软件
    4. 在内部软件上申请了访客码
    5. 你告诉外包同学访客码已经发到他的手机上了
    6. 外包同学拿着访客码进入京东大厦办理入职流程
    7. HR给他在内部办公软件上开通了一个erp账号
    8. 外包同学到达你所在的办公区,坐在工位上,打开电脑使用自己的erp账号访问你给他开通权限的代码库地址
    9. 外包同学将代码clone到了自己的电脑上

     三、OAuth 2.0的授权过程

    上一节中外包的例子基本可以解释OAuth 2.0的授权过程,但是存在一个问题就是:当他的ERP过期之后,如果还要继续在京东做项目,假设他想再进入京东大厦,是不是就要重新走一次访客码的过程,这个例子可能不是很恰当,但是对应到OAuth中,就是令牌(token)失效。一般为了保证token的安全性,token都有有效期,过了有效期之后如果想继续访问受保护的资源,可能还要重新走一遍授权流程,这个流程对客户端来说是比较繁琐的一种体验,为了提升这种体验,OAuth 2.0提供了一种刷新token机制,即在第一次返回token的同时会返回一个刷新token用于换取新的token,这个刷新token本身并不能访问受保护的资源,但是客户端可以用它换取新的可以访问受保护资源的有效token。完整的授权流程如下UML图所示:

    1.资源拥有者访问客户端应用,并表明他希望客户端代表自己去使用某一个受保护的资源

    2.当客户端发现需要获取一个新的OAuth访问令牌时,他会将资源拥有者重定向至授权服务器,并附带一个授权请求,表示他要向资源拥有者请求一些权限

    3.授权服务器会要求用户进行身份认证。这一步对确认资源拥有者的身份以及能向客户端授予哪些权限来说至关重要。

    • 用户身份认证直接在用户(浏览器)与授权服务器之间进行,这个过程对客户端应用不可见。这一特性避免了用户将自己的凭据暴露给客户端应用,对抗这种反模式正是发明OAuth的原因。
    • 因为资源拥有者是通过浏览器与授权服务器进行交互,所以也是通过浏览器来完成身份认证,所以就会有很多身份认证技术可以用户用户的身份认证流程。OAuth没用规定使用哪种身份认证技术,授权服务器可以自由选择,例如用户名密码、加密证书、安全令牌、联合单点登录等。

    4. 用户向客户端应用授权

       客户端可以在授权请求中指明其想要获取哪些权限,授权服务器可以允许用户拒绝一部分获取全部权限范围,也可以让用户批准或拒绝整个授权请求。此外,很多授权服务器允许将授权决策保留下来以便以后使用,这样可以在以后同一个客户端访问相同的授权时,无需提示用 户是否授权,授权服务器甚至可以通过客户端白名单、黑名单等策略来否决用户的否决。

    5.授权服务器将用户重定向回客户端应用

      在授权码模式中,重定向时回携带授权服务器生成的授权码code和客户端请求授权时的state,其中授权码code是一次性凭据,标识用户授权决策的结果,客户端会在接受到请求之后解析该参数以获取授权码,同时验证state是否与前一步的请求是否匹配。

    6.浏览器请求重定向地址中的客户端地址

    7.客户端通过授权码向授权服务器申请令牌

      客户端通过发送一个POST请求,以表单形式传递参数,并在header中设置client_id和client_secret,这两个参数一般都会加密后以Authorization:Basic 的形式发送。授权服务器接受该请求,需要进行如下验证,验证通过才能颁发token:

    • 验证客户端凭据(即client_id)以确定是哪个客户端的授权请求 
    • 从请求参数中获取授权码code,并获取关于该授权码的信息,包括发起初始授权请求的是哪个客户端?执行授权的是哪个用户?授权的内容是什么?
    • 如果该授权码有效且未被使用过,而且发起该请求的客户端与最初发起授权请求的客户端一致,则授权服务器会生成一个新的访问令牌兵返回给客户端

    8.客户端解析令牌响应,并从中获取token

    令牌响应中一般会包含令牌的类型token_type,访问令牌access_token,还会包含一个刷新令牌refresh_token,还有一些附加的信息,比如令牌的权限范围和过期时间等,客户端可以将令牌存放在一个安全的地方,以便在用户不在场时使用。

    9.客户端通过令牌token来访问受保护的资源

    10.客户端成功获取到受保护的资源

    11.当令牌过期之后,客户端可以通过令牌响应结果中返回的refresh_token,向授权服务器换取新的token,而不需要重新进行一次授权流程。

    12.授权服务器返回新的token供用户继续访问受保护的资源

    以上就是基于授权码模式的OAuth 2.0的完整授权流程。

    四、OAuth中的组件

    OAuth中除了四种主要角色之外,还有其他几种机制,如:令牌、授权范围、授权许可

    1、访问令牌(access_token)

    访问令牌,简称令牌,由授权服务区颁发给客户端,表示客户端已经被授予它所请求的权限,OAuth并没有定义令牌本身的格式和内容,它总代表着:客户端请求的访问权限、对客户端授予权限的资源拥有者、被授予的权,且令牌对于客户端是不透明的,客户端并不知道也不需要知道令牌所代表的含义,它只知道这是一串字符串,它只需要做到:持有令牌、向授权服务器请求令牌、向受保护资源出示令牌,授权服务器如何颁发令牌,受保护资源如何验证令牌它都无需关心。

    2、授权范围(scope)

    授权范围,表示一组访问受保护资源的权限,一般由受保护资源根据自身提供的API进行定义,它界定了客户端获取的权限范围,授权服务器则允许资源拥有者在客户端发出请求时许可或否决特定的权限范围。OAuth中使用字符串表示权限范围,可以用空格分割的列表将它们合并为一个集合,因此权限范围的值不能包含空格。

    3、刷新令牌(refresh_token)

    刷新令牌,与访问令牌的不同在于,该令牌不会被发送给受保护资源,它只是为了当访问令牌过期后,客户端不必重新发起授权请求,而是用该令牌向授权服务器请求换取一个新的用于获取受保护资源的访问令牌。

    五、OAuth的角色与组件的交互

    从OAuth 2.0的授权流程中可以知道,主要的几个流程有资源拥有者委托客户端访问受保护资源、客户端将资源拥有者重定向到身份认证页、用户完成身份认证、授权服务器重定向到客户端页面、客户端请求token、授权服务器颁发token、客户端请求受保护资源,其中由客户端、授权服务器和受保护资源参与的部分无需用户(浏览器重定向到身份认证页)的介入,这部分称之为“后端信道”,由资源拥有者、授权服务器和客户端参与的部分需要用户(浏览器重定向、身份认证等)的介入,这部分称之为“前端信道”,这块可能比较抽象,下面用几张图来描述就知道是怎么回事了~~~

    1、后端信道

    如上图中,后端信道的交互中,没有用户或浏览器的操作,都是服务之间的调用,用户无感知!

    2、前端信道

    如上图所示,前端信道中,用户访问客户端、客户端将用户重定向到身份认证页、用户进行身份认证、授权服务器返回授权码后重定向至客户端请求中的页面、用户将授权码发送给客户端都是需要用户的介入!

    3、端点

    授权服务器中的授权端点和令牌端点,授权和颁发令牌这两个虽然都属于授权服务器,但在实际的开发过程中,可以分为两个微服务。

    本文是对OAuth 2.0中基本概念的学习,文中的部分内容来自书本,因为感觉书中表述的还是很恰当,部分是按照自己的理解组织的语言,下一篇我会show出我的实战。最近了解到一种“费曼学习法”,大概意思就是用自己的语言解释你所学到的知识,然后把它讲给不懂的人听,如果别人能听懂,说明你也就学懂了。正在努力运用这种学习法,如果看到本文的你,有什么疑惑,欢迎提出来大家一起讨论,这样也能促进共同学习,共同进步,Respect~

    本文来自博客园,作者:bug改了我,转载请注明原文链接:https://www.cnblogs.com/hellowhy/p/15481745.html

  • 相关阅读:
    mysql外键(FOREIGNKEY)使用介绍
    MYSQL数据库-约束
    mysql探究之null与not null
    爬虫
    http://blog.csdn.net/w_e_i_/article/details/70766035
    Python 3.5安装 pymysql 模块
    Python 3.5 连接Mysql数据库(pymysql 方式)
    hdu Bone Collector
    hdu City Game
    hdu Largest Rectangle in a Histogram
  • 原文地址:https://www.cnblogs.com/hellowhy/p/15481745.html
Copyright © 2011-2022 走看看