reference:
- https://colobu.com/2017/04/28/oauth2-rfc6749/
- oauth2官网
- oauth1.0、oauth1.0a、oauth2区别
- access_token足够安全吗
1. 基本概念
Oauth2
一个标准的授权协议,用来解决如何安全的在客户端和服务器之间数据传递。oauth2面向一个通用模型,支持不通场景下的安全授权,能将暴露在互联网区的资源或服务安全可靠的提供出去。
1. 解决问题:
资源所有者为了给第三方应用提供受限资源的访问,需要与第三方共享它的凭据。 这造成一些问题和局限:
1. 需要第三方应用存储资源所有者的凭据,以供将来使用,通常是明文密码。
2. 需要服务器支持密码身份认证,尽管密码认证天生就有安全缺陷。
3. 第三方应用获得的资源所有者的受保护资源的访问权限过于宽泛,从而导致资源所有者失去对资源使用时限或使用范围的控制。
4. 资源所有者不能仅撤销某个第三方的访问权限而不影响其它,并且,资源所有者只有通过改变第三方的密码,才能单独撤销这第三方的访问权限。
5. 与任何第三方应用的让步导致对终端用户的密码及该密码所保护的所有数据的让步。
上述更具体点的描述可以将资源所有者
替换成微信
,受限资源
可以替换成微信账号信息
。
2. 概念抽象
OAuth通过引入授权层
以及分离客户端角色和资源所有者角色来解决这些问题。
在OAuth中,客户端在请求受资源所有者控制并托管在资源服务器上的资源的访问权限时,将被颁发一组不同于资源所有者所拥有凭据的凭据。
Oauth是一种客户端授权:客户端获得一个访问令牌(一个代表特定作用域、生命期以及其他访问属性的字符串),用以代替使用资源所有者的凭据来访问受保护资源。
访问令牌由授权服务器在资源所有者认可的情况下颁发给第三方客户端。客户端使用访问令牌访问托管在资源服务器的受保护资源。
2. 定义
ResourceOwner
资源所有者,能够许可受保护资源访问权限的实体。比如个人
ResourceServer
存放资源的服务器,能够接收和响应使用令牌对资源的请求。
Client
该客户端指第三方应用程序,具体请求资源服务器的客户端。而不是指浏览器这类客户端。
AuthorizationServer
授权服务器,主要用于验证资源所有者并授权分配令牌。授权>认证,基本上我们的授权都会有个认证的动作。在具体部署上、可以按实际项目也可以将资源服务器和授权服务器作为同一个应用来部署。
UserAgent
代理客户端,比如浏览器,手机App.
Authorization Code
授权码。授权标识,因为它会在浏览器上(非服务端)传输,而非服务端传递的数据我们都认定是不安全的,即使是https。所以它是短期有效的一次性数据。
Oauth2 openId
oauth2是授权协议,但我们可以看到平台都是基于oauth2实现的单点登录。这个其实就是oauth2-openId。openId是认证协议,而我们知道`授权>认证`。单点登录解决的就是多应用认证问题,oauth2-openId就是将用户信息作为资源服务提供出去。如果当前用户信息都能传递出去了,那么肯定能确定当前用户是谁了。
3. 流程
大致流程都是client申请授权、resourceServer分配token.
而为了解决多种授权场景,oauth2有4种授权模式
-
授权码模式-Authorization Code
支持场景:有服务端的应用。
主要就是使用authorization code 换取token。code安全性问题,所以才有后面的服务端交互token传递。
-
隐式许可模式-Implicit Grant
支持场景:纯前端应用,不含服务端。
授权回调地址后面直接拼上#access_token=xxx.需注意的是对该类应用的授权需要保证数据安全性问题。该access_token为弱安全性的token。
-
资源所有者密码校验-Resource Owner Password Credentials
支持场景: 涉及用户名和密码,所以此授权类型仅适用于可信赖的应用。比如自建App
-
客户端凭据-Client Credentials
支持场景:第三方应用授权,交互不涉及ResourceOwner.仅适用于获取与用户无关的公共信息。比如管理Api授权
3. 安全性
3.1 信息泄漏
主要包括 Authorization Code 泄漏、Access Token 泄漏、AppSecret 泄漏。
- Authorization Code 泄漏
解决方案:code一次性使用、缩小有效期 - Access Token 泄漏,泄漏分为链路传输泄漏和应用终端泄漏。
解决方案:- 链路传输上使用https
- 适量缩小token有效期
- 服务使用签名,签名包含appSecret.
- 重要服务进行二次校验
- AppSecret泄漏
这种场景就基本无法处理,你连appSecret都能泄漏出去了,还能保障什么安全。
虽然可以考虑对第三方应用配置白名单,但是会增加管理复杂度,不符合oauth2的目标。
3.2 CSRF
主要包括授权劫持和绑定劫持。授权劫持是指用户在目标网站处于登录状态的情况下,攻击者通过伪造授权链接来诱骗用户点击,用户访问攻击者的链接后,攻击者就会劫持用户授权。绑定授权同样是在用户处于登录状态的情况下,攻击者通过用户授权登录目标网站并阻断用户授权流程,进而诱骗用户点击,用户在访问攻击者的链接后,攻击者就可以劫持用户授权。
解决方案:
- state校验.在authorization_code模式中,申请授权链接带上state,授权成功分配code的时候会将state带回去。授权应用再将state与会话中的state进行对比。
3.3 URL 回调污染
主要是指由于 redirect_uri 回调地址填写不严格或者授权服务器不验证或者验证不严格而导致的 code 或者 access_token 泄露。
解决方案:
- 在应用管理中,配置应用的授权回调域,并在授权过程中校验授权回调域。
3.4 权限认证
主要是指 OAuth 高级授权接口的越权访问,比如 GitHub 的 scope 漏洞,导致可以访问私有代码区。
解决方案:
- 在服务上进行token权限级别划分
3.5 不区分调用方式
主要是指在 Authorization Code 和 Implicit 两个调用方式,它们的区别仅仅是一个参数,黑客可以利用这个参数来绕过 AppSecret 认证。
解决方案:
- 区分Authorization Code和Implicit 两个调用方式生成的token,两则可调用的服务不同。对于Implicit,我们只能保证一些基本的服务,比如获取用户id,像其他更具体的资源数据,我们需要保证数据安全性,比如数据脱敏。