OAuth2.0 官网简介
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 supersedes the work done on the original OAuth protocol created in 2006. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. This specification and its extensions are being developed within the IETF OAuth Working Group.
翻译:
OAuth2.0 是行业标准的授权协议。OAuth 2.0取代了2006年创建的原始OAuth协议所做的工作。OAuth 2.0专注于客户端开发人员的简单性,同时为Web应用程序,桌面应用程序,移动电话和客厅设备提供特定的授权流程。该规范及其扩展正在IETF OAuth工作组内开发。
如果是第一次看到OAuth2.0,并且没有对应的背景知识,再看到官网上的简介,是不能够理解,下面我们用一个例子去明白:
- OAuth2.0的应用场景
- OAuth2.0的workflow
相关例子阅读
参考文章
- OAuth2.0 RFC6749 协议官方文档
- OAuth2 RFC6749中文翻译
- OAuth2.0 原理简介 发表在博客园的 .NET西安社区博客上。
- 认证授权1.OAuth2授权 发表在博客园的 blackheart 博客上。
- OAuth2.0: Authorization Flows 发表在DannySite个人博客上。
- 理解OAuth 2.0 发表在阮一峰老师的个人网站网络日志模块。
- 专题我所知道的关于 OAuth 2 的资料
生活中例子场景:小李是一个文艺小青年, 经常喜欢出去旅游并且把自己旅行中的美景照片分享到各大社交网站上,比如朋友圈,新浪微博。小李马上要向女朋友求婚了,他想把这三年来和自己女朋友出去旅游的照片打印出来做成照片墙,好在求婚的时候讲女友感动的一塌糊涂,然后你懂得...,那么问题来了,按照小李带女朋友一个月出去玩一次,每次分享30张照片,三年就是30 * 12 * 3 = 1080 张,小李现在想把这1080张照片全部打印出来他首先得找个提供打印照片服务的公司(美图快印),然后把需要打印的照片给到服务公司然后才能打印。怎么把这些照片给到美图快印呢,一般来说有下面两种方式:
1. 小李到自己的微博相册中吭哧吭哧下载他需要打印的所有照片,然后装到U盘里或者转储到网盘里,再给到美图快印(那可是1080张照片啊,纯手工操作,好累啊)
2. 小李到美图快印告诉工作人员自己的账户名和密码,并告诉他那些需要打印,那些不需要打印,然后小李还会担心:自己和女友的亲密照被工作人员看到了怎么办(更可怕的是某一天自己会不会出现在某论坛上成为网红)?万一他记住了我的密码然后悄悄的登陆上去把我的密码改了怎么办?
小李觉得有点头疼了,有没有什么方法既不告诉工作人员自己的账号和密码又能够方便快捷的把照片给到美图快印呢?
2020年12月01日16:01:32,现在看上面这个例子不太好,引入了太多的不必要的背景
OAuth 出现的原因
在传统的客户端-服务器身份验证模式中,客户端请求服务器上限制访问的资源(受保护资源)时,需要使用资源所有者的凭据在服务器上进行身份验证。
资源所有者为了给第三方应用提供受限资源的访问,需要与第三方共享它的凭据。 这造成一些问题和局限:
- 需要第三方应用存储资源所有者的凭据,以供将来使用,通常是明文密码。
- 需要服务器支持密码身份认证,尽管密码认证天生就有安全缺陷。
- 第三方应用获得的资源所有者的受保护资源的访问权限过于宽泛,从而导致资源所有者失去对资源使用时限或使用范围的控制。
- 资源所有者不能仅撤销某个第三方的访问权限而不影响其它,并且,资源所有者只有通过改变第三方的密码,才能单独撤销这第三方的访问权限。
- 与任何第三方应用的让步导致对终端用户的密码及该密码所保护的所有数据的让步。
OAuth 核心 - 授权层
OAuth通过引入授权层以及分离客户端角色和资源所有者角色来解决这些问题。
在OAuth中,客户端在请求受资源所有者控制并托管在资源服务器上的资源的访问权限时,将被颁发一组不同于资源所有者所拥有凭据的凭据。
客户端获得一个访问令牌(一个代表特定作用域、生命期以及其他访问属性的字符串),用以代替使用资源所有者的凭据来访问受保护资源。
访问令牌由授权服务器在资源所有者认可的情况下颁发给第三方客户端。客户端使用访问令牌访问托管在资源服务器的受保护资源。
例如,终端用户(资源所有者)可以许可一个打印服务(客户端)访问她存储在图片分享网站(资源服务器)上的受保护图片,而无需与打印服务分享自己的用户名和密码。
反之,她直接与图片分享网站信任的服务器(授权服务器)进行身份验证,该服务器颁发给打印服务具体委托凭据(访问令牌)。
OAuth1 呢?
既然OAuth2.0中带有2这个数字,那么之前有没有OAuth1.0呢?
答案:有
OAuth 1.0协议(RFC5849)作为一个指导性文档发布,是一个小社区的工作成果。
本标准化规范在OAuth 1.0的部署经验之上构建,也包括其他使用案例以及从更广泛的IETF社区收集到的可扩展性需求。
OAuth 2.0协议不向后兼容OAuth 1.0。这两个版本可以在网络上共存,实现者可以选择同时支持他们。
OAuth2.0和例子的解析
为了方便将例子和OAuth2.0中的概念结合起来,我们先从例子本身摘出一些概念,然后和OAuth2.0中的概念一一映射。
例子中的一些主体概念
- 小李,我们可以理解小李是照片的拥有者
- 微博,可以理解为照片资源的存储的地方
- 美图快印,可以理解为想要访问小李所属的照片的第三方应用
OAuth2.0中的概念
- User / Resource owner,对应为小李(小李是User,也是照片的owner)
- Resource server,对应为微博(存储resource的地方)
- Client / Third-part Application,对应为美图快印(第三方应用)
- Authorization Server,OAuth2.0中进行授权的服务器,是解决例子中问题的关键概念。
OAuth2.0的运行流程
根据OAuth2.0的运行流程,我们可以模拟给出小李一个解决办法:
- 让美图快印向小李申请授权
- 小李同意授权
- 美图快印拿着小李的授权去到OAuth2.0 server去换令牌( NOTE:令牌对应的专业术语是 Access Token)
- OAuth2.0 server 确认是小李给的美图快印的授权后,给美图快印发放了令牌
- 美图快印拿着令牌愉快的去访问微博的照片
- 微博照片确认美图快印拿着的令牌是无误的,同意美图快印访问指定的照片资源
由OAuth2.0协议模拟出的小李打印照片的解决办法,我产生了以下疑问:
- 美图快印向小李申请授权,小李肯定要知道是谁要申请授权,授权的范围是多大,所以美图快印应该带的有:自己的身份(我是谁---美图快印), 目的(申请授权的目的---打印照片),需要的资源有哪些(授权的范围 --- 小李指定的范围还是美图快印指定的范围??)
- 小李看到美图快印的授权之后,知道了是美图快印,要打印照片,照片的范围(小李指定还是美图快印指定的?和1中的问题一样),
核心疑问:小李如何才能够给美图快印授权
- 美图快印拿到授权请求后,为什么要去OAuth2.0 Server(Authorization Server 授权服务器)拿令牌?授权和令牌有什么关系?
核心疑问:Authorization Server怎么能够让 Resource Owner,Client 和 Resource Server 关联起来
OAuth2.0 专业知识
为了解决上述的疑问,我们只能拿出OAuth2.0的专业知识来扫盲了。
由上述例子的OAuth2.0解决方案,可以看出OAuth2.0协议允许第三方应用(美图快印)在不知道用户(小李)密码的情况下,访问用户(小李)在某服务(微博)上的特定的私有资源。
OAuth2解决这个问题的关键在于使用Authorization server提供一个访问凭据给Client,使得Client可以在不知道Resource owner在Resource server上的用户名和密码的情况下消费Resource owner的受保护资源。
部署OAuth2.0的工作流
解决问题的核心就是OAuth2.0 引入的Authorization Server,那么如何搭建一个Authorization Server? 并且Authorization Server 如何管理 Resource Owner, Resource Server 和 Client的关系?
Resource Server需要做的事情:
- 增加一个Authorization Server,提供授权实现,一般是由Resource Server来提供。
- Resource Server 为第三方应用程序提供注册接口
- Resource Server 开放相应的受保护资源的API
Client需要做的事情:
- Client 注册成为Resource Server的第三方应用
- Client 消费这些API
作为资源提供服务商来说,1,2,3这三件事是需要完成的。
作为第三方应用程序,要完成的工作是4,5两步骤。
其中,作为Resource Owner来说,是不用做什么的,最多在页面上点个同意授权的按钮。
OAuth2.0 的授权模式
也可以理解为Client的授权模式:
- 授权码模式(authorization code)
- 简化模式 或者 隐式许可 (implicit)
- 密码模式 或者 资源所有者密码凭证(resource owner password credentials)
- 客户端模式 (client credentials)
授权码模式(authorization code)
QQ互联使用的就是授权码模式(authorization code)。QQ 互联中授权码模式官网解析。
授权码通过使用授权服务器做为客户端与资源所有者的中介而获得。客户端不是直接从资源所有者请求授权,而是引导资源所有者至授权服务器,授权服务器之后引导资源所有者带着授权码回到客户端。
在引导资源所有者携带授权码返回客户端前,授权服务器会鉴定资源所有者身份并获得其授权。由于资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据不需要与客户端分享。
- (A) 客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。
- (B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。
- (C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI包括授权码和之前客户端提供的任何本地状态。
- (D)客户端通过包含上一步中收到的授权码从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。客户端包含用于获得授权码的重定向URI来用于验证。
- (E)授权服务器对客户端进行身份验证,验证授权代码,并确保接收的重定向URI与在步骤(C)中用于重定向客户端的URI相匹配。如果通过,授权服务器响应返回访问令牌与可选的刷新令牌。
隐式许可(implicit)
隐式许可是为用如JavaScript等脚本语言在浏览器中实现的客户端而优化的一种简化的授权码流程。在隐式许可流程中,不再给客户端颁发授权码,取而代之的是客户端直接被颁发一个访问令牌(作为资源所有者的授权)。这种许可类型是隐式的,因为没有中间凭据(如授权码)被颁发(之后用于获取访问令牌)。
当在隐式许可流程中颁发访问令牌时,发授权服务器不对客户端进行身份验证。在某些情况下,客户端身份可以通过用于向客户端传送访问令牌的重定向URI验证。访问令牌可能会暴露给资源所有者,或者对资源所有者的用户代理有访问权限的其他应用程序。
隐式许可提高了一些客户端(例如一个作为浏览器内应用实现的客户端)的响应速度和效率,因为它减少了获取访问令牌所需的往返数量。然而,这种便利应该和采用隐式许可的安全影响作权衡,尤其是当授权码许可类型可用的时候。
资源所有者密码凭证(resource owner password credentials)
资源所有者密码凭据(即用户名和密码),可以直接作为获取访问令牌的授权许可。这种凭据只能应该当资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。
客户端模式 (client credentials)
当授权范围限于客户端控制下的受保护资源或事先与授权服务器商定的受保护资源时客户端凭据可以被用作为一种授权许可。典型的当客户端代表自己表演(客户端也是资源所有者)或者基于与授权服务器事先商定的授权请求对受保护资源的访问权限时,客户端凭据被用作为授权许可。
OAuth2.0 思维导图(Draft Version)
2020年12月01日 再次理解OAuth2.0
有一个妈妈,想使用宝宝孕育树APP,但是没有选择直接在宝宝孕育树APP进行注册,而是使用了微信进行授权。
思考:如果是宝宝孕育树App把宝妈带到微信App进行授权,那么也就是说宝宝孕育树App实现了微信授权流程。
这个例子里宝妈使用的是手机,所以查看微信的移动应用进行授权功能的集成,可以看到的是移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0 授权登录系统。
文档要求需要准备工作有:
- 微信开放平台注册的开发者账号
- 拥有一个已经审核通过的移动应用,并且获得 AppID 和 AppSecret
OKTA 文章中关于OAuth的内容
https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth#oauth-flows