OAuth 1.0
一、基本概念
1、概述
OAuth 1.0 是一种用于授权的开放标准,它允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用。
定义:OAuth1.0 是一个开放标准,通过提供临时令牌(而非用户名和密码)来访问用户资源,以此增强安全性。
目的:OAuth1.0 旨在简化客户端的授权流程,同时保证用户的数据安全。
2、特点
1) 简单性: OAuth1.0 的流程和接口设计相对简单,易于理解和实现。
2)安全性:通过引入签名机制,确保请求的完整性和安全性,防止请求被篡改。
3)开放性:任何服务提供商都可以实现OAuth1.0, 任何软件开发商都可以使用OAuth1.0进行应用开发。
3、授权流程
OAuth1.0的授权流程通常包括以下几个步骤:
1. 请求Request Token: 第三方应用向服务提供者请求一个未授权的Request Token。
2. 用户授权:服务提供者将用户重定向到第三方应用的授权页面,用户在此页面上进行授权操作。
3. 请求Access Token: 用户授权后,第三方应用使用Request Token向服务提供者请求Access Token。
4. 访问资源:第三方应用使用Access Token访问用户资源。
4、签名机制
OAuth1.0通过签名机制来确保请求的完整性和安全性。签名过程通常包括以下几个步骤:
1)创建签名基本字符串:将HTTP请求方法、请求URL和请求参数按照特定格式拼接成签名基本字符串。
2)编码和拼接密钥:将OAuth令牌密钥(Token Secret)和应用程序密钥(Consumer Secret)进行URL编码,并用"&"符合拼接成签名密钥。
3)生成签名:使用HMAC-SHA1 算法将签名基本字符串和签名密钥进行加密,生成签名结果。
4)添加签名到请求:将签名结果进行Base64编码和URL编码后,添加到请求参数中的“oauth_signature”参数。
5、OAuth1.0 的安全性和局限性
- 安全性: OAuth1.0 通过签名机制提供了一定程度的安全性,但仍然存在一些安全漏洞,如签名方法(如SHA-1)的潜在弱点、跨站请求伪造(CSRF)等。
- 局限性:OAuth1.0的复杂性和安全性问题使得它在现代应用中的使用逐渐减少。相比之下,OAuth2.0提供了更高的安全性和更简单的流程,成为目前广泛使用的版本。
6、OAuth1.0 的应用场景
尽管OAuth1.0逐渐被OAuth2.0所取代,但在一些旧系统或特定应用场景下中,OAuth1.0仍然被使用。例如,一些旧版本的社交媒体平台或API可能仍然支持OAuth1.0授权。
7、总结
OAuth1.0 是一种用于授权的开放标准,它通过提供临时令牌访问用户资源,同时保护用户的数据安全。然而,由于存在安全漏洞和复杂性等问题,OAuth1.0在现代应用中使用逐渐减少。相比之下,OAuth2.0 提供了更高的安全性和更简单的流程,成为目前广泛使用的版本。对于需要集成OAuth授权功能的应用开发者来说,建议优先考虑使用OAuth2.0。
二、QQ空间使用OAuth1.0实例
参考地址Qzone_OAuth_1.0认证简介 — QQ互联WIKI
1、说明
QQ空间 OAuth认证基于OAuth1.0协议,为了保护腾讯QQ空间用户的数据,所有第三方网站都需要通过OAuth认证机制来获得用户的授权。
用户通过“QQ登录”登录网站并在网站上访问或修改他们在QQ空间上的数据(照片,日志,分享等)的整个处理流程。
目前QQ登录已支持OAuth2.0协议,采用OAuth2.0标准协议来进行用户身份验证和获取用户授权,相对于OAuth1.0协议,其认证流程更简单和安全。
2、总体流程
- 起点: 用户在网站上点击“QQ登录”标识,使用QQ账户登录网站
- Step1: 网站向Qzone发送request请求临时token。
- Step2:Qzone接受请求,返回未授权的临时token。
- Step3: 网站引导用户到QQ登录窗口; 用户输入用户名和密码,点击"登录"按钮后,网站向Qzone发送request,请求已授权的临时token。
- Step4:Qzone获取用户登录状态;引导用户授权允许网站其QQ空间连接(仅在用户初次使用”QQ登录“登录网站时需要);返回已授权的临时token,并引导用户跳转回网站(该回调地址已在step3的请求中指定)。
- Step5:网站向Qzone发送request,请求具有Qzone访问权限的access_token。
- Step6:Qzone接受请求,返回具有Qzone访问权限的access_token。
- 注:在step6 和 step7 之间,网站可以将用户的QQ号码与网站账户绑定。这一步不是必须的,一般来说该步骤仅针对已经有了自己账号体系的网站。
- Step7:网站调用QQ登录OpenAPI向Qzone发送request,请求访问或修改Qzone受保护的资源(例如用户资料,日志,相册,说说等信息)。
- 终点: Qzone接受请求,返回step7中请求的资源或执行对资源的修改。
3、详细说明
step1:网站向Qzone发送request,请求临时token
用户点击了”QQ登录“后,相当于向网站服务器发送了一个请求指令。网站服务器这时候要做一件事,就是发送下面的请求到QZone的接口。
http://openapi.qzone.qq.com/oauth/qzoneoauth_request_token
请求带上一些关键参数
- oauth_consumer_key: 网站的开发者,先得去QQ平台申请,QQ分配给网站一个openid,就是这个参数值。
- oauth_nonce: 随机字符串,用于签名串。
- oauth_timestamp: unix时间戳,用于签名串。
- oauth_version: 版本号,固定用1.0。
- oauth_signature_method: 签名方法,固定使用HMAC-SHA1。
- oauth_signature: 签名值,用来提高传输过程参数的防篡改性。
- oauth_client_ip: 用户的IP地址(可选)。
用户点击了网站的一个按钮后,用户浏览器发送一个请求到网站的某个自定义的接口上,这时候,网站服务器还没有响应用户的点击操作,而是网站服务器向QQ服务器发了这个请求,QQ服务就会返回一个临时token。
网站肯定先得和QQ平台签订协议,成为QQ平台的一个合法的注册商家,网站就有有自己的openid。这个接口用的oauth_consumer_key就是用来标识网站的身份的。网站除了consumer_key,还会有个consumer_secret, 对于这个请求,网站服务端会用这个consumer_key对请求内容进行签名,这样能防止篡改,签名内容包含了时间戳和随机字符串,能有效进行防重放攻击。
总体来说,就是网站通过自身已经申请得到的consumer_key和consumer_secret向QQ平台申请一个token,表明自己想要用户授权权限。
step2:Qzone接受请求,返回未授权的临时token
QQ的服务器收到网站的请求后,会返回临时token
- oauth_token : 未授权的临时token
- oauth_token_secret: 未授权的临时token对应的密钥
网站的服务器通过API调用QQ服务器接口拿到了结果(临时的未授权token),这是两个服务器之间http请求返回内容,此时用户的点击操作产生的网站请求还没返回呢。
step3:网站引导用户到QQ登录窗口,获取已授权的临时token
http://openapi.qzone.qq.com/oauth/qzoneoauth_authorize
带上三个参数
- oauth_consumer_key: 申请QQ登录后,分配给网站的appid
- oauth_token: 未授权的临时token,请使用上一步中返回的oauth_token
- oauth_callback: 回调地址。在用户授权成功后,会从QQ登录页面跳转回这里指定的回调地址。
这里是网站服务端拿到返回的临时token后,得引导用户进行授权,引导的方式,就是通过重定向来实现。先重定向用户到QQ授权页面并提供了一个callback,一旦用户确认授权,他是跟QQ服务器交互,但是QQ服务器拿到callback,就能再把用户重定向到网站,并带上授权后的信息。
这里,就是网站服务器拼接出一个url,让用户的点击请求被重定向到这个url上,也就是QQ的授权页面。这里有临时token,QQ服务器能验证这个token,也有consumer_key, 两者结合起来,就知道用户访问的什么网站,这个网站和用户都知道要授权的事情。
step4:Qzone引导用户跳转到第三方应用
第三步是让用户访问到授权页面,用户授权后,会让用户请求被重定向到step3指定的回调地址。这个回调地址,实际上就是网站服务器的一个地址,用于让用户把QQ服务器授权后的信息附带到url上,然后能传给网站服务器。
这个回调url上面会被QQ服务器带上参数
- oauth_token: 已授权的临时token
- openid: 与APP通信的用户key,它和QQ号码一一对应,访问OpenAPI时必须。同一个QQ号码在不同的应用中有不同的OpenID。
- oauth_signature: 签名值。如果网站使用这一步的openid,则需要按规则生成签名值,并于该签名值比对,以验证openid以及来源的可靠性。
- timestamp:openid的时间戳
- oauth_vericode: 授权验证码
用户看到QQ服务器给我授权页面后,点击授权。这时候是用户的浏览器把请求发给QQ服务器。服务器判定用户身份等并进行授权。授权后,QQ服务器按照上一步给的回调地址,用用户请求重定向到了网站服务器。
通过重定向,把一些授权信息就给到了服务器了。包括授权后的token,还有openid是这个用户的唯一标识。
step5:网站请求具有Qzone访问权限的access_token
前面几步,本质就是引导用户授权,授权成功后,QQ服务器让用户重定向到网站,带上了授权的token。
此时网站的回调url被访问后,网站会请求QQ服务端要access_token, 地址:http://openapi.qzone.qq.com/oauth/qzoneoauth_access_token
会带上很多参数
- oauth_consumer_key: 申请QQ登录成功后,分配给网站的appid
- oauth_token: 已授权的临时token,请使用上一步返回的oauth_token
- oauth_nonce: 随机字符串,用于签名串。
- oauth_timestamp: unix时间戳,用于签名串。
- oauth_version: 版本号,固定用1.0。
- oauth_signature_method: 签名方法,固定使用HMAC-SHA1。
- oauth_signature: 签名值,用来提高传输过程参数的防篡改性。
- oauth_client_ip: 用户的IP地址(可选)。
- oauth_vericode: 授权验证码,请使用上一步返回的oauth_vericode
前面几个步骤,实际就是网站想要用户信息,就引导用户授权,用户授权后,用户带着授权信息访问服务器,服务器拿到授权信息。这时候,服务器已经有了用户的openid,有了授权token。就能调用QQ服务器拿用户信息并进行一些授权的操作了。
但是这里得先用授权的token和授权码oauth_vericode去换取access_token。
step6:Qzone返回具有Qzone访问权限的access_token
qq服务器收到access_token请求,就会返回内容如下
- oauth_token: 具有访问权限的access_token
- oauth_token_secret: access_token的密钥
- openid: 与APP通信的用户key,它和QQ号码一一对应,访问OpenAPI是必需。同一个QQ号码在不同的应用中有不同的OpenID。
- timestamp:openid的时间戳
- oauth_signature: 针对openid的签名值。
step7:网站调用OpenAPI,访问或修改空间受保护的资源
将请求发送到某个具体的OpenAPI,请求参数包含如下内容
- oauth_consumer_key: 申请QQ登陆成功后,分配给网站的appid。
- oauth_token: 具有访问权限的access_token, 请使用上一步返回的oauth_token
- oauth_timestamp: unix时间戳
- oauth_version: 版本号,固定1.0
- oauth_signature_method: 签名方法,固定使用HMAC-SHA1。
- oauth_signature: 签名值,用来提高传输过程参数的防篡改性。
- openid: 请传入上一步返回的openid。
- oauth_client_ip: 用户的IP地址(可选)。
一旦网站拿到了access_token,后续用户在网站上操作,网站是有权限直接调用QQ服务器进行一些授权范围内的操作的,比如拿用户信息等等。
4、代码实现
从上面的流程图以及流程描述中可以看到,Step 1,3,5,6是需要网站参与的。
三、OAuth1.0的缺点
1. 认证流程复杂
- 多步骤认证:OAuth1.0的认知流程相对复杂,通常包括多个步骤,如请求Request Token、用户授权、交换Request Token为Access Token等。这些步骤增加了开发的复杂性和用户的操作难度。
- 繁琐的签名机制:OAuth1.0 要求客户端在请求时包含复杂的签名信息,包括时间戳、随机字符串、签名方法等,这些签名机制虽然提高了安全性,但也增加了实现的难度。
2. 安全性问题
- 密钥泄露风险:OAuth1.0,客户端需要存储Request Token和Request Token Secret等敏感信息,这增加了密钥泄露的风险。一旦密钥泄露,攻击者可以伪装成合法客户端进行访问。
- 易受中间人攻击:在OAuth1.0的某些实现中,如果未使用HTTPS等安全协议,传输过程中的敏感信息可能被中间人截获和篡改。
- 已知安全漏洞:OAuth 1.0在早期版本中存在一些已知的安全漏洞,如通过trap site攻击获取用户的Access Token等。虽然这些漏洞在后续版本中得到了修复,但这也反映了OAuth 1.0在安全性方面的不足。
3. 扩展性和灵活性不足
-
流程固定:OAuth1.0 的认证流程相对固定,缺乏灵活性,难以满足不同场景下的需求。
-
token管理不便:OAuth 1.0中,Access Token通常被设计为长期有效,这可能导致网站架构的破坏和安全隐患。同时,缺乏有效的token更新机制,使得token管理变得困难。
4. 不兼容性和维护问题
- 不兼容性: OAuth2.0作为OAuth1.0的后续版本,在安全性、简单性和灵活性方面进行了大量改进。然而,OAuth2.0并不兼容OAuth1.0,这意味着从OAuth1.0迁移到OAuth2.0需要进行大量的改动和调整。
- 维护问题:由于OAuth 1.0已经逐渐被OAuth 2.0所取代,因此其相关的支持和维护可能会逐渐减少。这可能导致在使用OAuth 1.0时遇到问题时难以获得及时的帮助和支持。
综上所述,OAuth 1.0虽然为Web服务的授权提供了基础框架,但在认证流程、安全性、拓展性和灵活性以及兼容性和维护性等方面存在一些问题。因此,在选择授权协议时,建议优先考虑OAuth 2.0等更先进、更安全的版本。
OAuth2.0
一、隐式授权模式 - Implicit Grant
1.1 概念
步骤:
(A) 客户端通过将资源所有者的user-agent重定向到授权端点来初始化授权流程,客户端需要携带客户端标识、请求授权的范围、state以及重定向URI(当授权通过或拒绝时,授权服务器将user-agent重定向回该URI)。
(B) 授权服务器对资源所有者进行认证,并确认资源所有者的授权还是拒绝客户端的访问请求。
(C) 假设资源所有者同意授权,那授权服务器将使用之前提供的重定向URI将user-agent重定向回客户端。在重定向URI的fragment部分会包含访问令牌。
(D) user-agent会遵循重定向指令,向基于web的客户端发起请求(不包含fragment部分[RFC2616]), frament由user-agent自行处理。
(E) 基于web的客户端会返回一个web页面(一般是包含内置脚本的HTML文件),该页面有访问包含fragment在内的整个重定向URI的权限,并且会从fragment中获取到访问令牌。
(F) user-agent执行客户端返回的脚本,用于解析获取访问令牌。
(G) user-agent将访问令牌传给客户端。
通俗说明: 看着这些步骤,并不好理解。看使用场景更容易理解实际,使用场景就是单前端项目,没有后端项目的场景。用户浏览器访问云端,云端是vue项目,就能返回html在浏览器加上。 这个纯前端项目运行需要用户授权,所以把用户请求引导授权服务器,用户授权后,授权服务器让浏览器重定向。重定向到一个vue写好的页面,页面里面的逻辑就是把访问地址中的token拿到。后续的浏览器上操作,都带着token能访问到需要授权的服务。
1.2 详细步骤说明
1.2.1 授权请求 - Authorization Request
客户端构造出发给授权端点的请求。
请求参数:
- response_type: 必须。值必须为“token”。
- client_id: 必须。客户端标识。
- redirect_uri:可选。重定向uri。
- scope:可选。请求访问的范围。
- state:建议。客户端用来维护请求和回调之间状态的不透明值。授权服务器将user-agent重定向回客户端时会携带该值。该值一般用于防止跨站请求伪造攻击。
客户端通过HTTP重定向的响应或其它可行的方式,将资源所有者的user-agent引导到构造的URI。比如客户端引导user-agent通过TLS发起如下请求:
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
授权服务器需要检验请求中所有必须的参数是否传入且有效,并且要检验即将用于传递访问令牌的重定向URI,是否与客户端注册时提供的重定向URI完全匹配。
如果请求校验通过,授权服务器将引导资源所有者进行授权,并且让其做出授权决策(通过询问资源所有者,或建立其它有效的授权方式)。
当用户完成其授权决策后,授权服务器将通过HTTP重定向或其它可行的方式,将user-agent引导到重定向URI。
通俗说明: 这里的客户端,一般就是已经加载到浏览器的网页内容(html、css、js),比如vue做的web应用。 当用户访问或点击时,触发授权请求步骤,构造请求发到授权端点。授权服务器校验通过后,通过重定向方式,让浏览器执行重定向,即在请求vue的某个页面,这能触发一些页面返回,页面带着从url中截取token保存到浏览器本地的逻辑,这样的目的是把授权token给到客户端。
1.2.2 访问令牌响应 - Access Token Response
如果资源所有者授权了访问请求,授权服务器需要签发访问令牌,并按照约束要求,把内容添加到重定向URI的查询组件部分。
- access_token: 必须。授权服务器签发的访问令牌。
- token_type: 必须。令牌类型,大小写敏感。
- expires_in: 建议。访问令牌的寿命,以秒为单位。比如值为“3600”,代表访问令牌将在响应的一小时后过期。
- scope:当与请求中列举的范围相同时,则该返回值可选;否则必须返回。
- state: 当授权请求中包含该字段时,必须原样返回。
授权服务器不得签发刷新令牌。
授权服务器通过如下的HTTP响应对user-agent进行重定向:
HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
&state=xyz&token_type=example&expires_in=3600
开发者必须注意,某些user-agent并不支持在HTTP的Location头中包含fragment组件,这一类的客户端不能使用3xx重定向响应,而是需要提供其它方式对user-agent进行重定向,比如返回一个包含"continue"按钮的HTML页面,在点击后跳转到重定向URI。
客户端必须忽略未定义的响应参数。访问令牌的长度并未在该规范中定义,因此客户端应该避免假设该字段的长度。授权服务器应明确签发的所有值的长度。
如果授权请求由于重定向URI或客户端标识参数存在问题(丢失、无效或不匹配)导致请求失败,授权服务器应该告知资源所有者出现异常,而不是自动将user-agent重定向到无效的重定向URI。
通俗说明: 客户授权了,授权服务器让浏览器回调URI,这样我们在我们的vue做的项目中,其云端提供了这个URI,浏览器访问后,vue就能拿到token,在通过http的响应,可以把token给到浏览器,也就算是给到了用户。在后续请求中,就能带上这个token。
1.3 安全风险
1.令牌泄露风险:
- 由于隐式授权模式将访问令牌(access token)直接附加在重定向URI的片段标识符(fragment identifier)中,并通过浏览器返回给客户端,这增加了令牌被泄露的风险。如果攻击者能够拦截或篡改浏览器与服务器之间的通信(尽管HTTPS可以减少这种风险),就有可能获取到令牌。
- 一旦令牌泄露,攻击者就可以使用该令牌访问受保护的资源,从而可能对用户或系统造成损害。
2. 跨站脚本(XSS)攻击风险:
- 由于隐式授权模式依赖于浏览器来传递令牌,因此它特别容易受到跨站脚本攻击的影响。如果攻击者能够在用户的浏览器中执行恶意脚本,就有可能窃取或篡改令牌。
3. 令牌管理复杂性:
- 尽管隐式授权模式简化了授权流程,但它也增加了令牌管理的复杂性。由于令牌直接返回给客户端,客户端需要负责令牌的存储、保护和使用。如果客户端的存储机制不够安全,或者没有正确地处理令牌的生命周期(如定期刷新令牌),就可能导致安全风险。
4. 限制和局限性:
- 隐式授权模式通常只适用于特定的客户端类型(如基于浏览器的客户端),并不适用于所有类型的客户端。此外,由于它直接在浏览器和认证服务器之间传递令牌,因此可能无法提供与更安全的授权流程(如授权码流程)相同的保护级别。
5. 不符合最佳实践:
- 尽管隐式授权模式在某些情况下可能是必要的,但它通常不被视为最佳实践。OAuth 2.0的官方文档和许多安全专家都建议,在可能的情况下,应优先考虑使用更安全的授权流程(如授权码流程),以提供更好的安全性和灵活性。
为了减轻隐式授权模式的风险,可以采取以下措施:
- 使用HTTPS:确保所有与认证服务器和客户端之间的通信都通过HTTPS进行,以防止中间人攻击和令牌泄露。
- 存储令牌的安全方式:客户端在接收到令牌后,应将其存储在安全的位置(如使用浏览器的Web存储API进行加密存储),并确保不会在不安全的环境中暴露令牌。
- 限制令牌的有效期:设置较短的令牌有效期,并定期进行刷新,以减少令牌被滥用的风险。
- 监控和日志记录:对与令牌相关的活动进行监控和日志记录,以便在发生安全事件时能够及时发现和响应。
总之,隐式授权模式虽然提供了便利性和简单性,但也存在显著的安全风险。在选择使用隐式授权模式时,需要仔细评估其安全性和适用性,并采取适当的措施来减轻风险。
1.4 适用场景
隐式授权模式(Implicit Grant)在OAuth 2.0协议中是一种简化的授权流程,主要用于某些类型的客户端(如JavaScript客户端运行在浏览器中),这些客户端无法安全地存储机密信息(如客户端密钥)。
例如:问卷调查、评论
二、授权码模式 - Authorization Code Grant
2.1 概念
授权码模式可用于同时获取访问令牌和刷新令牌,对非公开客户端也有所优化。由于该模式依赖重定向,因此客户端必须具备同资源所有者的user-agent(典型的如web浏览器)交互的能力,同时也要具备接收授权服务器请求的能力(通过重定向)。
(A) 客户端通过将资源所有者的user-agent重定向到授权端点来初始化授权码流程,客户端需要携带客户端标识、请求授权的范围、state以及重定向URI(当授权通过或拒绝时,授权服务器将user-agent重定向回该URI)。
(B) 授权服务器对资源所有者进行认证,并确认资源所有者是授权还是拒绝客户端的访问请求。
(C) 假设资源所有者授权允许客户端的访问,授权服务器会将user-agent重定向到之前提供的重定向URI(授权请求中或者客户端注册时提供的),重定向URI中会包含授权码,以及之前客户端提供的state参数。
(D) 客户端通过上述步骤中获取的授权码,向授权服务器请求访问令牌。当发起该请求时,客户端需要进行身份认证,此外,参数中也需要包含换取授权码时携带的重定向URI,以作为验证。
(E) 授权服务器对客户端进行认证,验证授权码是否正确,并确保重定向URI与步骤C中的完全匹配,如果验证通过,授权服务器将返回访问令牌,也可能包含刷新令牌。
2.2 详细步骤说明
2.2.1 授权请求 - Authorization Request
客户端使用附录B中说明的"application/x-www-form-urlencoded"格式,去构造授权端点的请求参数:
- response_type: 必须。值必须为“token”。
- client_id: 必须。客户端标识。
- redirect_uri:可选。重定向uri。
- scope:可选。请求访问的范围。
- state:建议。客户端用来维护请求和回调之间状态的不透明值。授权服务器将user-agent重定向回客户端时会携带该值。该值一般用于防止跨站请求伪造攻击。
客户端通过HTTP重定向的响应或其它可行的方式,将资源所有者的user-agent引导到构造的URI。
比如,客户端引导user-agent通过TLS发起如下请求:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com
授权服务器验证授权请求,以确保所有必须的参数都已提供并且经过验证,如果验证通过,授权服务器将验证资源所有者的身份,并获取其是否授权的决定(通过询问资源所有者,或建立其它的同意机制)
当用户完成其授权决策后,授权服务器将通过HTTP重定向或其它可行的方式,将user-agent引导到重定向URL。
2.2.2 授权响应 - Authorization Response
如果资源所有者授予了访问权限,授权服务器将签发一个授权码,并且通过附录B中定义的"application/x-www-form-urlencoded"格式将如下参数组织到重定向URI的查询参数中。
- code
- 必须。授权码由授权服务器生成,且授权码不应该维持太长时间,以减小泄露的风险,一般建议最长维持10分钟。客户端不能多次使用同一个授权码,如果某个授权码出现多次使用的情况,授权服务器应该拒绝当前的请求,并且吊销由该授权码签发的所有令牌。授权码与客户端标识和重定向URI存在绑定关系。
- state
- state 必须。该值为客户端发起授权请求时传递的值(有传则在此时返回)。
例如,授权服务器会通过如下HTTP响应对user-agent进行重定向动作:
HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
&state=xyz
客户端必须忽略无法识别的响应参数。此规范未定义授权码字符串的长度,因此客户端应避免预设授权码的长度。授权服务器应该记录所有签发的值的长度。
如果授权请求由于重定向URI或客户端标识参数存在问题(丢失、无效或不匹配)导致请求失败,授权服务器应该告知资源所有者出现异常,而不是自动将user-agent重定向到无效的重定向URI。
2.2.3 访问令牌请求 - Access Token Request
客户端按照附录B中的"application/x-www-form-urlencoded"格式组织如下参数,并使用UTF-8编码后放在HTTP请求体中,发送到token端点:
- grant_type 必须。值必须为"authorization_code"。
- code 必须。授权服务器返回的授权码。
- redirect_uri 必须。如果授权请求中有携带redirect_uri参数,那跟此次的值必须完全一致。
- client_id 必须,如果客户端如章节3.2.1所述未进行认证。
如果客户端类型是非公开客户端,或者有签发过客户端凭证(或其它认证方式),那客户端必须如章节3.2.1中所述与授权服务器进行认证。
比如,客户端通过TLS发送如下请求:
POST /token HTTP/1.1
Host: server.example.com
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_id指定的客户端。
-
验证授权码的有效性,并且:
-
如果授权请求中包含redirect_uri参数,则此处也必须包含,且值必须一致。
2.2.4 访问令牌响应 - Access Token Response
如果访问令牌请求是有效且经过客户端认证的,那授权服务器返回访问令牌和可选的刷新令牌。如果客户端认证失败,则授权服务器返回错误响应。
如下是成功响应的案例:
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"
}
三、密码模式(Resource Owner Password Credentials Grant)
3.1 概念
如果你高度信任某个第三方应用,可以把用户名和密码告诉你这个第三方应用,第三方应用拿到用户名和密码去申请授权获取令牌。在这种模式中,用户必须把自己的密码给客户端,但是客户端不得存储密码。
这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名的公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。
(A) 用户向第三方客户端提供用户名和密码。
(B) 第三方客户端将用户名和密码发给授权服务器,申请令牌。
(C) 授权服务器确认无误后向第三方客户端发放令牌。
3.2 优缺点
优点:
-
简单直接:密码模式流程相对简单,客户端直接收集用户的用户名和密码,然后向授权服务器请求访问令牌。这种方式减少了授权过程中的交互步骤,对于某些应用场景来说,可能更加直接和高效。
-
适用范围广:在一些场景下,如原生应用或客户端无法支持其他授权模式时,密码模式可以作为一种有效的替代方案。它特别适用于那些客户端可以安全地存储用户凭据,并且用户信任该客户端的情况。
-
用户体验好:对于用户来说,只需要在客户端上输入一次用户名和密码,就可以获得授权并访问受保护的资源,这减少了在多个应用之间切换和登录的麻烦。
缺点:
-
安全风险高:密码模式最大的缺点在于安全风险。客户端需要直接处理用户的用户名和密码,这增加了密码泄露的风险。如果客户端的安全性不足,或者被恶意软件攻击,那么用户的密码就可能被窃取。
-
不符合OAuth 2.0的设计初衷:OAuth 2.0的设计初衷是避免客户端直接处理用户的敏感信息,如密码。密码模式违反了这一原则,使得客户端成为了安全链中的薄弱环节。
-
依赖客户端的安全性:密码模式的有效性高度依赖于客户端的安全性。如果客户端无法确保存储和处理用户密码的安全性,那么使用该模式就会带来很大的安全隐患。
-
可能受到政策限制:由于密码模式存在较高的安全风险,一些政策或标准可能会限制或禁止使用该模式。例如,某些行业或地区的法规可能要求使用更加安全的授权模式来保护用户信息。
四、客户端凭证模式(Client Credentials Grant)
4.1 概念
(A) 客户端向授权服务器发起认证并请求获取访问令牌。
(B) 授权服务器验证客户端身份,如果通过,则签发访问令牌。
4.2 详细步骤
4.2.1 授权请求和响应 - Autorization Request and Response
使用客户端凭证模式时,不需要发起授权请求。
4.2.2 访问令牌请求
客户端把下面的参数放置在HTTP的请求体中,来访问令牌端点:
- grant_type 必须。值为"client_credentials"。
- scope 可选。
客户端需要如章节3.2.1所述进行客户端认证。
比如,客户端通过TLS发起如下的HTTP请求:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
授权服务器必须对客户端进行认证。
4.2.3 访问令牌响应
如果访问令牌请求有效且授权通过,则授权服务器签发访问令牌(不得签发刷新令牌)。如果请求无效或授权失败,则返回错误响应。
4.3 适用场景
适用于自家产品、微服务中,需要从接口层面发起请求的场景。
参考:
认证授权:OAuth2简介及四种授权模型详解-腾讯云开发者社区-腾讯云 (tencent.com)
OAuth2.0的四种授权模式 - alittlesmile - 博客园 (cnblogs.com)
OAuth 2.0 扩展协议之 PKCE - SpringLeee - 博客园 (cnblogs.com)
深入理解OAuth 2.0:原理、流程与实践-腾讯云开发者社区-腾讯云 (tencent.com)
OAuth 2.0授权框架中文版 [4.1] - 授权码模式_the request is missing a required parameter, inclu-CSDN博客
OAuth 2.0授权框架中文版 [4.2] - 隐式授权模式_the authorization server encountered an unexpected-CSDN博客