文章干货内容较多,请耐心观看
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。简单来说就是提供除了"账户密码"验证方式以外的验证授权方式。
如果一个用户拥有两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。如下图所示。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了两个用户,假设这两个用户名各不相同,密码也各不相同。当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理?法一:用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;法二:用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。
很多公司和个人都尝试解决这类问题,包括Google、Yahoo、Microsoft,这也促使OAUTH项目组的产生。OAuth是由Blaine Cook、Chris Messina、Larry Halff 及David Recordon共同发起的,目的在于为API访问授权提供一个开放的标准。OAuth规范的1.0版于2007年12月4日发布。通过官方网址:http://oauth.net可以阅读更多的相关信息。
OAuth1.0协议中,一共定义了三种关键角色:
在弄清楚OAUTH流程之前,我们先了解下OAUTH的一些术语的定义:
400 401 等Http协议代码
认证流程如下:
A. 使用者(第三方软件)向OAUTH服务提供商请求未授权的Request Token。向Request Token URL发起请求,请求需要带上的参数见上图。
B. OAUTH服务提供商同意使用者的请求,并向其颁发未经用户授权的oauth_token与对应的oauth_token_secret,并返回给使用者。
C. 使用者向OAUTH服务提供商请求用户授权的Request Token。向User Authorization URL发起请求,请求带上上步拿到的未授权的token与其密钥。
D. OAUTH服务提供商将引导用户授权。该过程可能会提示用户,你想将哪些受保护的资源授权给该应用。此步可能会返回授权的Request Token也可能不返回。
E. Request Token 授权后,使用者将向Access Token URL发起请求,将上步授权的Request Token换取成Access Token。请求的参数见上图,这个比第一步A多了一个参数就是Request Token。
F. OAUTH服务提供商同意使用者的请求,并向其颁发Access Token与对应的密钥,并返回给使用者。
G. 使用者以后就可以使用上步返回的Access Token访问用户授权的资源。
从上面的步骤可以看出,用户始终没有将其用户名与密码等信息提供给使用者(第三方软件),从而更安全。用OAUTH实现背景一节中的典型案例:当服务B(打印服务)要访问用户的服务A(图片服务)时,通过OAUTH机制,服务B向服务A请求未经用户授权的Request Token后,服务A将引导用户在服务A的网站上登录,并询问用户是否将图片服务授权给服务B。用户同意后,服务B就可以访问用户在服务A上的图片服务。整个过程服务B没有触及到用户在服务A的帐号信息。如下图所示,图中的字母对应OAUTH流程中的字母:
上述描述的是OAuth 1.0 协议最初的标准,随着时间的发展,发现了其中存在重大漏洞,后来协议进行完善,可以认为出现了OAuth 1.0a版本,详细可参考https://blog.csdn.net/joeyon1985/article/details/42026039
https://blog.csdn.net/joeyon1985/article/details/42025477 ,文章中详细介绍了协议的漏洞之处以及如何进行的修复(1.0a版本)。
实际上OAuth1.0 最终版(已经成为RFC5849 标准)已经没有这个安全的漏洞了,但是OAuth 协议( RFC5849 标准)文档上提出了以下安全考量,对应 http://tools.ietf.org/html/rfc5849#section-4
似乎说 RSA_SHA1 更安全
建议用 SSL 或者 TLS 保证请求的安全
建议用 SSL 或者 TLS 保证确认服务提供者的身份
客户端 proxy 或者 cache 的安全
服务端密钥的安全存储
客户端密钥的安全存储
警告用户,防止用户的疏忽
由于第三方应用的不可信任(可能希望获取更多的用户资源),需对授权的资源严格的分类,并告知明确用户可能存在的风险
密钥的安全性,最好是真正的随机数
DOS/DDOS 攻击
SHA-1 自身的漏洞
签名只是保证了 base_string 的完整
CSRF ( Cross Site Request Forgery )
Clickjacking
客户端密钥的安全
协议 1.0 定稿后,已经广泛使用,其本身不会有什么安全漏洞,但协议的实现可能存在漏洞,这是我们需要花精力去测试的。由于参数众多,实现复杂,加上以上对于安全考量的思考,2012年OAtuh 2.0 协议发布。
2012年10月,OAuth 2.0协议正式发布为RFC 6749。现在百度开放平台,腾讯开放平台等大部分的开放平台都是使用的OAuth 2.0协议作为支撑。
在OAuth 2.0的认证和授权的过程中主要包括以下角色定义:
OAuth 在 “客户端” 与 “服务提供商” 之间,设置了一个授权层(authorization layer)。“客户端” 不能直接登录 “服务提供商”,只能登录授权层,以此将用户与客户端区分开来。“客户端” 登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。“客户端” 登录授权层以后,“服务提供商” 根据令牌的权限范围和有效期,向 “客户端” 开放用户储存的资料。
RFC 6749 中写到:(由于互联网有多种场景,)本标准定义了获得令牌的四种授权方式(authorization grant )。
这四种模式如下:
授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
过程如下:
有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)。
过程如下:
这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。
如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。
过程如下:
这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。
最后一种方式是凭证式(client credentials),适用于没有前端的命令行应用,即在命令行下请求令牌。
过程如下:
这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。
A 网站拿到令牌以后,就可以向 B 网站的 API 请求数据了。
此时,每个发到 API 的请求,都必须带有令牌。具体做法是在请求的头信息,加上一个Authorization字段,令牌就放在这个字段里面。
curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"
上面命令中,ACCESS_TOKEN就是拿到的令牌。
令牌的有效期到了,如果让用户重新走一遍上面的流程,再申请一个新的令牌,很可能体验不好,而且也没有必要。OAuth 2.0 允许用户自动更新令牌。
具体方法是,B 网站颁发令牌的时候,一次性颁发两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。
- | OAuth1.0 | OAuth2.0 |
---|---|---|
是否兼容 | - | OAuth 2.0是个全新的协议 |
token有效期 | 有效期非常长的token(典型的是一年有效期或者无有效期限制) | 短有效期的access token和长生命期的refresh token。这将允许客户端无需用户再次操作而获取一个新的access token,并且也限制了access token的有效期 |
协议 | http | https |
过程 | 伴随复杂的签名算法等 | 轻量,提供多种方式 |
------------------------------------------- 参考博文 -------------------------------------
https://blog.csdn.net/hereweare2009/article/details/3968582
https://blog.csdn.net/joeyon1985/article/details/42026039
https://blog.csdn.net/joeyon1985/article/details/42025477
https://blog.csdn.net/qq_28077405/article/details/105549707
http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html