OAuth 核心 1.0
Abstract
OAuth协议致力于使网站和应用程序(统称为消费方)能够在无须用户透露其认证证书的
情况下,通过API访问某个web服务(统称为服务提供方)的受保护资源。更一般地说,
OAuth为API认证提供了一个可自由实现且通用的方法。
一个典型的例子是某打印服务提供商printer.example.com(消费方),希望在无须用户
提供其照片存储站点密码的情况下,访问用户储存在photos.example.net(服务提供方)
上的个人照片。
OAuth不强求一个特定的用户接口或操作模式,也不限定服务提供方如何验证用户,特别
适合认证证书对消费方不可用的情况,例如OpenID。
OAuth致力于为托管web服务认证提供统一的体验和实现,形成一个社区驱动的协议。
OAuth构建于已被多个站点独立实现的已有协议和最佳化实践之上,是一个被大小服务提
供者所支持、并为应用开发者和用户增进持续性和可信度的开放标准。
Table of Contents
1. 作者
2. 记号与惯例
3. 术语定义
4. 文档与注册
4.1. 请求URL
4.2. 服务提供方
4.3. 消费方
5. 参数
5.1. 参数编码
5.2. 消费方请求参数
5.3. 服务提供方响应参数
5.4. OAuth HTTP认证方案
6. 使用OAuth认证
6.1. 获取未授权的请求令牌
6.2. 获取用户授权
6.3. 获取访问令牌
7. 访问受保护资源
8. 单次值与时间戳
9. 签署请求
9.1. 签署基字符串
9.2. HMAC-SHA1
9.3. RSA-SHA1
9.4. PLAINTEXT
10. HTTP响应代码
Appendix A. Appendix A - Protocol Example
Appendix A.1. Documentation and Registration
Appendix A.2. Obtaining a Request Token
Appendix A.3. Requesting User Authorization
Appendix A.4. Obtaining an Access Token
Appendix A.5. Accessing Protected Resources
Appendix B. Security Considerations
Appendix B.1. Credentials and Token Exchange
Appendix B.2. PLAINTEXT Signature Method
Appendix B.3. Confidentiality of Requests
Appendix B.4. Spoofing by Counterfeit Servers
Appendix B.5. Proxying and Caching of Authenticated Content
Appendix B.6. Plaintext Storage of Credentials
Appendix B.7. Secrecy of the Consumer Secret
Appendix B.8. Phishing Attacks
Appendix B.9. Scoping of Access Requests
Appendix B.10. Entropy of Secrets
Appendix B.11. Denial of Service / Resource Exhaustion Attacks
Appendix B.12. Cryptographic Attacks
Appendix B.13. Signature Base String Compatibility
11. References
§ Author's Address
TOC
1. 作者
Mark Atwood (me@mark.atwood.name)
Richard M. Conlan (zeveck@google.com)
Blaine Cook (blaine@twitter.com)
Leah Culver (leah@pownce.com)
Kellan Elliott-McCrea (kellan@flickr.com)
Larry Halff (larry@ma.gnolia.com)
Eran Hammer-Lahav (eran@hueniverse.com)
Ben Laurie (benl@google.com)
Chris Messina (chris@citizenagency.com)
John Panzer (jpanzer@acm.org)
Sam Quigley (quigley@emerose.com)
David Recordon (david@sixapart.com)
Eran Sandler (eran@yedda.com)
Jonathan Sergent (sergent@google.com)
Todd Sieling (todd@ma.gnolia.com)
Brian Slesinsky (brian-oauth@slesinsky.org)
Andy Smith (andy@jaiku.com)
TOC
2. 记号与惯例
本文中的这些关键词“必须”、“不得”、“要求”、“应”、“不应”、“需”、“不
可”、“推荐”、“可以”和“可选”在[RFC2119]中解释。 例子中的域名参考
[RFC2606]。
TOC
3. 术语定义
服务提供方 Service Provider:
一个允许通过OAuth访问的web应用程序。
用户 User:
在服务提供方处拥有帐号的个人。
消费方 Consumer:
一个代表用户以OAuth形式访问服务提供方的网站或应用程序。
受保护资源 Protected Resource(s):
服务提供方所掌控的数据,能被通过用户认证的消费方访问。
消费方开发者 Consumer Developer:
实现消费方的个人或组织。
消费方键值 Consumer Key:
消费方用来向服务提供方标示身份的值。
消费方密钥 Consumer Secret:
消费方用于建立对消费方键值所有权的密钥。
请求令牌 Request Token:
消费方用于从用户处获得授权并换取请求令牌的值。
访问令牌 Access Token:
消费方用于代表用户在没有密码的情况下访问受保护资源的值。
令牌密钥 Token Secret:
消费方用于建立对特定令牌所有权的密钥。
OAuth协议参数 OAuth Protocol Parameters:
参数名称,以oauth_开头。
TOC
4. 文档与注册
在OAuth里,服务提供方以一组消费方键值和消费方密钥来鉴定消费方(正如用登录名和
密码来鉴定用户)。 这种识别方式使得服务提供方可以向消费方开放不同的访问级别。
服务提供方不应依赖消费方密钥来验证消费方的身份,除非能确保消费方密钥不被第三方
获知。消费方密钥可以是一个空串,例如消费方无需验证或使用RSA等其他方式验证。
TOC
4.1. 请求URL
OAuth定义了三种类型的请求URL:
请求令牌URL:
用于获得一个未授权的请求令牌,详见Section 6.1.
用户授权URL:
用于用户向消费方授权,详见Section 6.2.
Access Token URL:
用于将已授权的请求令牌换取访问令牌,详见Section 6.3.
三种URL必须包含方案、授权和路径,可以包含[RFC3986]第三部分所定义的查询和片段,
不得(MUST NOT)包含任何OAuth协议参数。例如:
http://sp.example.com/authorize TOC
4.2. 服务提供方
服务提供方负责为消费方开发者创建消费方键值和消费方密钥,所需条件和过程由服务提
供方决定。
服务提供方文档包括:
消费方所使用的请求URL、访问请求令牌URL和访问令牌URL所使用的HTTP方法。
服务提供方支持的签名方法。
获取令牌所需的其他附加请求参数,不得以oauth_开头。
TOC
4.3. 消费方
消费方开发者必须在服务提供者处创建一组消费方键值和消费方密钥。注册时开发者可能
会被服务提供方要求提供某些附加信息。
TOC
5. 参数
OAuth协议的参数名称和值都是大小写敏感的。每次请求中的参数不得重复出现,除非说
明否则都是必须的。
TOC
5.1. 参数编码
所有参数名称和值都必须根据[RFC3986]所定义的百分号机制进行转义。 保留字符集
([RFC3986] section 2.3)内的不得被编码,其它的必须被编码,编码后的十六进制字符
必须大写。 百分号转换前的参数名称和值的文本必须是UTF-8编码,见[RFC3629]。
非保留字符 = 字母, 数字, '-', '.', '_', '~'
TOC
5.2. 消费方请求参数
从消费方向服务提供方发送OAuth协议参数使用以下三种形式之一(按优先度降序):
OAuth HTTP认证方案中定义的HTTP Authorization首部。
一个content-type为application/x-www-form-urlencoded的HTTP POST请求体内。
作为URL中的查询部分(定义于[RFC3986]第三部分)。
另外,未来的扩展部分可能增加额外的方式以传送OAuth协议参数。发送其他请求参数的
方法不被定义,但不应使用OAuth HTTP 认证方案首部.
TOC
5.3. 服务提供方响应参数
服务提供方在HTTP响应体内向消费方返回令牌和其他信息。参数名称和值先按照参数编码
所述进行编码 ,然后按照[RFC3986] Section 2.1 定义的方式用'&'字符(ASCII代码38)
连接起来,例如:
oauth_token=ab3cd9j4ks73hf7g&oauth_token_secret=xyz4992k83j47x0b
TOC
5.4. OAuth HTTP认证方案
本部分定义了[RFC2617]以支持OAuth。使用标准的HTTP Authorization和
WWW-Authenticate首部来传送OAuth协议参数。
推荐服务提供方接受HTTP Authorization首部,消费方应当能够以Authorization首部形
式发送OAuth参数。
扩展的认证方案(由[RFC2617]定义)是大小写不敏感的OAuth。
TOC
5.4.1. Authorization 首部
Authorization首部中的OAuth协议参数按照以下规则发送:
参数和值按照Parameter Encoding编码。
每个参数名后跟一个'='字符(ASCII代码61)、一个'"'字符(ASCII代码34)、参数值(可以
为空)和另一个'"'字符(ASCII代码34)。
依照[RFC2617],多个参数以逗号(ASCII代码44)分隔,外加一个可选的换行和空白。
可选参数realm按照[RFC2617], section 1.2 被添加和解释。
例如:
Authorization: OAuth realm="http://sp.example.com/",
oauth_consumer_key="0685bd9184jfhq22",
oauth_token="ad180jjd733klru7",
oauth_signature_method="HMAC-SHA1",
oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
oauth_timestamp="137131200",
oauth_nonce="4572616e48616d6d65724c61686176",
oauth_version="1.0"
TOC
5.4.2. WWW-Authenticate 首部
消费方请求受保护资源时,服务提供方可以返回OAuth HTTP WWW-Authenticate首部表明
对OAuth扩展的支持。 按照[RFC2617] ,回应可以包含附加的WWW-Authenticate头:
例如:
WWW-Authenticate: OAuth realm="http://sp.example.com/"
按照[RFC2617], section 1.2,realm参数定义了受保护区域,
TOC
6. 使用OAuth认证
OAuth认证是指用户在不共享其证书(密码)的前提下授权消费方访问其受保护资源的过
程。 在请求受保护资源的过程中OAuth使用服务提供方生成的令牌替代了用户的证书。
这一过程使用两种类型的令牌:
请求令牌:
用于消费方向用户请求对访问受保护资源的授权。 经过用户授权的请求令牌可以换取一
个访问令牌,只能使用一次,不得用于其他用途。 建议为请求令牌设置一个有限的生命
期。
访问令牌:
用于消费方代表用户访问受保护资源。 访问令牌可以被用于限制访问特定资源,可以只
有有限的生命期。 服务提供方应当允许用户收回访问令牌。应当只有访问令牌被用于访
问受保护资源。
OAuth认证由以下三个步骤完成:
消费方获得未授权的请求令牌。
用户授权请求令牌。
消费方用请求令牌换取访问令牌。
TOC
6.1. 获取未授权的请求令牌
消费方向服务提供方的请求令牌URL发起一个HTTP请求,服务提供方的文档指定了可以使
用的HTTP方法,推荐使用POST。 请求必须被签署并包含以下参数:
TOC
6.1.1. 消费方获取请求令牌
消费方向服务提供方的请求令牌URL发起一个HTTP请求,服务提供方的文档指定了可以使
用的HTTP方法,推荐使用POST。 请求必须被签署并包含以下参数:
oauth_consumer_key:
消费方键值。
oauth_signature_method:
消费方签署本请求所用的签名方法。
oauth_signature:
签名,定义于签署请求。
oauth_timestamp:
定义于Nonce and Timestamp。
oauth_nonce:
定义于Nonce and Timestamp。
oauth_version:
可选。如果存在,其值必须为1.0。如果参数不存在,服务提供方必须假定协议版本为1.0
。 服务提供方对1.0以外取值的响应尚未定义。
额外参数:
由服务提供方定义的任意额外参数。
TOC
6.1.2. 服务提供方签发未授权的请求令牌
服务提供方校验签名和消费方键值。如果成功则生成一个请求令牌和令牌密钥并在HTTP响
应体中返回,见服务提供方响应参数。服务提供方必须确保请求令牌在用户授权成功之前
不能被换取访问令牌,见获取用户授权.
响应包含如下参数:
oauth_token:
请求令牌
oauth_token_secret:
令牌密钥
附加参数:
由服务提供方定义的任意参数。
如果请求验证失败或由于其他原因被拒绝,服务提供方应当回应以适当的响应代码,见
HTTP响应代码。服务提供方可以在响应体内包含关于被拒绝原因的详细信息,见服务提供
方相应参数。
TOC
6.2. 获取用户授权
获取用户授权之前,消费方不能使用使用请求令牌。获取用户授权包含以下步骤:
TOC
6.2.1. 消费方引导用户至服务提供方
为了能够换取访问令牌,消费方必须引导用户到服务提供方处并获得用户的核准。为此,
消费方构造一个指向服务提供方用户授权URL的HTTP GET请求,包含以下参数:
oauth_token:
可选。在前述步骤中获得的请求令牌。服务提供方可以声明此参数为必须,也可以允许不
包含在授权URL中并提示用户手工输入。
oauth_callback:
可选。消费方可以指定一个URL,当 获取用户授权成功后,服务提供方将重定向用户到这
个URL。
附加参数:
由服务提供方定义的任意参数。
消费方构造请求URL并通过用户的浏览器将用户重定向到该地址。如果消费方无法自动进
行HTTP重定向,则须告知用户如何手工访问该地址。
注意:如果服务提供方已知消费方运行于移动设备或机顶盒, 则应保证用户授权URL和请
求令牌适于手工输入。
TOC
6.2.2. 服务提供方认证用户并获取许可
服务提供方验证用户身份并询问用户是否许可。OAuth不指定服务提供方如何鉴定用户,
但定义了以下必须的步骤:
服务提供方询问用户许可前,必须先验证用户身份,如用户未登录可以要求其先登录。
服务提供方向用户展示消费方访问请求相关的信息,包括访问时限、被访问资源等,也可
以包含其他 服务提供方指定的信息。
用户必须授权或否决服务提供方允许消费方代表用户访问受保护资源。一旦用户否决,服
务提供方不得允许消费方访问受保护资源。
当服务提供方根据消费方键值显示关于消费方的信息时,必须向用户告知其是否能确保此
信息的确实可靠,而所使用的方式不在本规范讨论范围之内。
TOC
6.2.3. 服务提供方将用户引导回消费方
用户通过服务提供方认证并对消费方授权后,消费方必须被告知请求令牌已被授权并可以
交换访问令牌。如果用户否决的访问,则消费方可以被告知请求令牌已被回收。
如果消费方在oauth_callback中提供了回调URL(在消费方引导用户至服务提供方中描述)
,则服务提供方构造一个HTTP GET请求URL,重定向用户浏览器到该URL,并包含如下参数
:
oauth_token:
被用户授权或否决的请求令牌
回调URL可以包含消费方提供的查询参数,服务提供方必须保持已有查询不变并追加
oauth_token参数。
如果没有提供回调URL则服务提供方告知用户手工通知消费方授权完成。
TOC
6.3. 获取访问令牌
消费方用请求令牌换取访问令牌以访问受保护资源。获取访问令牌包含以下步骤:
TOC
6.3.1. 消费方请求访问令牌
请求令牌及其密钥必须被交换为访问令牌及其密钥。
消费方向服务提供方发起一个HTTP请求以获取访问令牌。服务提供方的文档指定了所使用
的HTTP方法,建议使用POST。请求必须按照签署请求签署, 并包含以下参数:
oauth_consumer_key:
消费方键值。
oauth_token:
之前获取的请求令牌。
oauth_signature_method:
消费方使用的签署方法。
oauth_signature:
签署请求中定义的签名。
oauth_timestamp:
在单次值与时间戳中定义。
oauth_nonce:
在单次值与时间戳中定义。
oauth_version:
可选。如果存在,其值必须为1.0。如果参数不存在,服务提供方必须假定协议版本为1.0
。 服务提供方对1.0以外取值的响应尚未定义。
请求访问令牌时,不得包含其他服务提供方指定的附加参数,以确保所有令牌相关信息都
是之前用户确认时存在的。
TOC
6.3.2. 服务提供方授予访问令牌
服务提供方必须确保:
请求签名验证成功。
请求令牌从未被交换过访问令牌。
请求令牌与消费方键值相符。
如果成功,服务提供方生成访问令牌及其密钥,并在HTTP响应体中返回,如服务提供方响
应参数之定义。消费方保存访问令牌及其密钥,并用以签署对受保护资源的请求。响应包
含如下参数:
oauth_token:
访问令牌。
oauth_token_secret:
令牌密钥。
附加参数:
服务提供方指定的附加参数。
如果请求验证失败或由于其他原因被拒绝,服务提供方应当回应以适当的响应代码,见
HTTP响应代码。服务提供方可以在响应体内包含关于被拒绝原因的详细信息,见服务提供
方响应参数。
TOC
7. 访问受保护资源
成功收到访问令牌及其密钥后,消费方即可代表用户访问受保护资源。 请求必须按照签
署请求进行签署,并包含如下参数:
oauth_consumer_key:
消费方键值。
oauth_token:
访问令牌。
oauth_signature_method:
消费方使用的签署方法。
oauth_signature:
签署请求中定义的签名。
oauth_timestamp:
定义于单次值与时间戳.
oauth_nonce:
定义于单次值与时间戳.
oauth_version:
可选。如果存在,其值必须为1.0。如果参数不存在,服务提供方必须假定协议版本为1.0
。 服务提供方对1.0以外取值的响应尚未定义。
附加参数:
服务提供方指定的附加参数。
TOC
8. 单次值与时间戳
请求时间戳用格林威治时间1970年1月1日0时0分0秒起的秒数表示,除非服务提供方另外
指定。 请求时间戳必须是个正整数,并必须不小于上一个请求中的时间戳。
消费方必须为一个时间戳的所有请求的生成不同的单次值。 单次值是一个随机字符串,
是为每次请求生成的唯一值。 服务提供方用单次值验证一个请求之前从未被发起过,有
助于防止非安全通道(例如HTTP)上的重放攻击。
TOC
9. 签署请求
所有对令牌和受保护资源的请求都必须被消费方签署并由服务提供方验证。 对请求进行
签署是为了防止未经授权的第三方使用使用消费方键值和令牌请求令牌和受保护资源。
签署的过程是将消费方密钥和令牌密钥编码为可校验的值并包含在请求中。
OAuth不强制要求特定的签署方法,每个实现可以有其特定的要求。 协议定义了三种方法
:HMAC-SHA1、RSA-SHA1和PLAINTEXT,服务提供者也可自由实现并在文档中描述其他办法
。 对特定签署方法的推荐不在本文表述范围之内。
消费方在oauth_signature_method参数中声明一个签署方法,生成一个签名并存储于
oauth_signature参数中。 服务提供方根据指定的方法验证签名。 验证签名时,服务提
供方应检查单次值,确保之前的请求中未被使用过。
签署过程中,不得改变除oauth_signature外的任何参数。
TOC
9.1. 签署基字符串
签署基字符串(Signature Base String)就是将请求元素串接为单个字符串,该过程的
结果是一致的、可重复的。 该字符串用于散列或签署算法的输入。 HMAC-SHA1签署方法
提供了签署基字符串用于签署算法的一个标准和实例。 生成签署基字符串所有请求参数
必须按照参数编码进行编码。
TOC
9.1.1. 正常化请求参数
请求参数被收集起来,排序并串接为一个普通的字符串:
除realm以外OAuth HTTP Authorization 首部中的参数
HTTP POST请求体中的参数(content-type为application/x-www-form-urlencoded)。
HTTP GET URL中的查询部分参数(定义于 [RFC3986] section 3).
oauth_signature参数必须被排除。
参数按照以下方式正常化为一个字符串:
按照参数名字典顺序排序。同名参数按其值排序,例如:
a=1, c=hi%20there, f=25, f=50, f=a, z=p, z=t
已排序参数串接为一个字符串。 每个参数名后跟一个“=”字符(ASCII代码61),无论
参数值是否为空。 每对参数之间用“&”字符(ASCII代码38)分开。例如:
a=1&c=hi%20there&f=25&f=50&f=a&z=p&z=t
TOC
9.1.2. 构造请求URL
签署基字符串包含了请求的绝对URL,以确保签名和特定终点的捆绑。 签署基字符串中的
URL必须包含方案、授权和路径,必须排除[RFC3986] section 3所定义的查询和片段部分
。
如果绝对地址对服务提供方不可用(对消费方总是可用的),则根据当前使用的方案、
HTTP Host 首部、相对请求URL组合而成。 如果Host首部不可用,则服务提供方应使用文
档中或其他方式下对消费方通讯使用的主机名。
服务提供方应当在文档中说明签署基字符串中所使用URL的形式,以避免URL正常化过程中
混淆。 除非特别指定,URL方案和认证都必须小写,并包含端口号;HTTP默认端口80和
HTTPS默认端口443必须被排除。
例如,如下请求:
HTTP://Example.com:80/resource?id=123在签署基字符串中被包含为如下:
http://example.com/resource TOC
9.1.3. 串接请求字符串
以下项必须被依次串接成为一个字符串。 每一项都按照编码参数进行编码,无论是否为
空都用“&”字符(ASCII代码38)分开。
发送请求所使用的HTTP方法,必须大写,例如: HEAD、GET、POST等。
前述构造请求URL.
前述请求参数正常化得到的字符。
参考Appendix A.5.1中的范例。
TOC
9.2. HMAC-SHA1
HMAC-SHA1签署方式使用[RFC2104]中定义的HMAC-SHA1签署算法,把签署基字符串作为
text, key则由先按照参数编码进行编码再用“&”字符(ASCII代码38)分隔(无论是否
为空)的消费方密钥和令牌密钥串接而成。
TOC
9.2.1. 生成签名
oauth_signature被设置为digest字节串, 先按照[RFC2045] section 6.8 base64编码,
再按照参数编码进行URL编码。
TOC
9.2.2. 验证签名
服务提供方使用如下步骤验证请求: 首先生成一个新的请求签名,将消费方提供的签名
先按照Parameter Encoding进行请求解码, 再按照 [RFC2045] section 6.8 进行base64
解码,然后将两者进行比较。 服务提供方用于生成签名的是消费方的请求参数及本地存
储的消费方密钥和令牌密钥。
TOC
9.3. RSA-SHA1
RSA-SHA1签署方式使用[RFC3447] section 8.2 (通常被称为 PKCS#1)中定义的
RSASSA-PKCS1-v1_5签署算法,使用SHA-1作为EMSA-PKCS1-v1_5的散列算法。假定消费方
已通过某种可验证的途径(不在本规范讨论范围之内)向服务提供方提供了RSA公钥。
TOC
9.3.1. 生成签名
签署基字符串按照[RFC3447] section 8.2.1 使用消费方的RSA私钥进行签署, K 为消费
方的RSA私钥,M为签署基字符串,S为签署结果字节串:
S = RSASSA-PKCS1-V1_5-SIGN (K, M)
oauth_signature被设置为S,先按照 [RFC2045] section 6.8 进行base64编码,然后按
照 Parameter Encoding进行URL编码。
TOC
9.3.2. 验证签名
服务提供方按照[RFC3447]section 8.2.2 验证签名, 其中(n, e) 为消费方RSA公钥, M
为签署基字符串, S为oauth_signature代表的字节值:
RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)
TOC
9.4. PLAINTEXT
纯文本(PLAINTEXT)方式不提供任何安全保护,应当仅被用于安全通道如HTTPS之上。该
方式不使用签署基字符串。
TOC
9.4.1. 生成签名
oauth_signature被设置为编码后的消费方密钥和令牌密钥的串接值,用'&'字符(ASCII代
码38)分隔,无论密钥是否为空。 结果必须被再次编码。
以下例子给出了在消费方密钥为djr9rjt0jd78jf88, 而令牌密钥分别为三个不同的值时
得到的oauth_signature值:
jjd999tj88uiths3:
oauth_signature=djr9rjt0jd78jf88%26jjd999tj88uiths3
jjd99$tj88uiths3:
oauth_signature=djr9rjt0jd78jf88%26jjd99%2524tj88uiths3
空:
oauth_signature=djr9rjt0jd78jf88%26
TOC
9.4.2. 验证签名
服务提供方将签名拆分出消费方密钥和令牌密钥,分别与本地存储的值进行比较验证。
TOC
10. HTTP响应代码
本部分仅适用于对请求令牌和访问令牌的请求。一般地说,服务提供方应当使用
[RFC2616] Section 10中定义的响应代码。 当服务提供方拒绝一个消费方的请求时,应
当返回HTTP 400 Bad Request 或HTTP 401 Unauthorized。
HTTP 400 Bad Request
Unsupported parameter
Unsupported signature method
Missing required parameter
Duplicated OAuth Protocol Parameter
HTTP 401 Unauthorized
Invalid Consumer Key
Invalid / expired Token
Invalid signature
Invalid / used nonce
【 在 jjgod (while(!asleep()) sheep++;) 的大作中提到: 】
:
http://oauth.net/: An open protocol to allow secure API authentication in a simple and
: standard method from desktop and web applications.
--
FROM 221.222.237.145