OAuth2.0介绍
OAuth 2.0是用于授权的行业标准协议,允许用户让第三方应用访问该用户在某一网站受保护的资源(比如user API),而无需将用户名和密码提供给第三方应用。OAuth 2.0专注于简化客户端开发,同时为web应用程序、桌面应用程序、移动电话和客厅设备提供特定的授权流程。
角色划分
- resource owner:资源所有者,能够授予第三方应用访问特定保护资源的权限。 当资源所有者是个人时,它是被称为最终用户。
- resource server: 资源服务器,受保护的资源一般通过携带访问令牌(access token)的API请求来访问。资源服务器通过访问authorzation server检查访问令牌(accessToken)的有效性。如果令牌有效并且权限合法,则允许访问
- client: 第三方应用,资源所有者通过client应用发起访问保护资源请求;
- authorization server: 授权服务器会给通过认证和授权的client发放访问令牌(access server受保护的资源;
举个例子: 微信用户小王通过微信账号登录广发理财产品系统购买基金,登陆时候跳转到微信登录授权页面,授予理财产品系统访问个人昵称、头像的权限。这个场景里,对应的角色如下:
- resource owner: 微信用户小王,拥有保护信息(访问个人昵称、头像等)
- resource server: 微信平台(提供个人信息的api系统)
- authorization server: 微信平台(提供登录以及授权的系统)
- client: 广发理财产品系统
OAuth2.0协议
+--------+ +---------------+ | |--(1)- Authorization Request ->| Resource | | | | Owner | | |<-(2)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(3)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(4)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(5)----- Access Token ------>| Resource | | | | Server | | |<-(6)--- Protected Resource ---| | +--------+ +---------------+
- client向resource owner发起授予权限的请求。该授权请求可以直接向resource owner发起,也可以通过authorization server中转发起。 建议通过授权服务器作为中间人发起授权申请。
- 如果resource owner同意授权,client将收到授权信息,授权类型。 授权类型(grant type)有authorization code, implicit, resource owner password
credentials, and client credentials。支持自定义授权类型。 - client向authorization server发起获取访问令牌的请求。不同授权类型请求参数不同。
- authorization server认证client信息和授权类型的合法性。如果合法,则方法令牌(access token)。
- client通过访问令牌访问resource server的保护资源。
- resource server检查访问令牌的合法性以及权限的合规性,如果合法合规,则允许访问保护资源。
授权方式(Authorization Grant)
分为authorization code, implicit, resource owner password
credentials, and client credentials四种授权方式,支持自定义的授权方式。
授权码模式(authorization code)
- 授权码是获取访问令牌access token的临时凭证
- 授权码从认证服务器获取
- 授权码不是从资源所有者(resource owner)直接获取,而是把资源所有者(resource owner)引导到认证服务器(authorization server)进行认证和授权,通过之后携带授权码重定向到client。
- 认证服务器对凭证和权限进行验证,认证通过给client授权码;
- 资源所有者的凭证不会泄露给client,因为认证是在认证服务器完成
- access token直接从认证服务器重定向到client,不经过资源所有者的浏览器等,通信更安全
隐藏模式(Implicit)
- 通过浏览器Javasciprt脚本获取访问令牌
- 只有前端没有后端的场景
- 认证服务器直接返回访问令牌(access token)
- 认证服务器不对客户端进行认证
- access token可能会暴露在资源所有者的user-agent
- 提高响应性,单有安全隐患
密码模式(resource owner password credentials)
- 直接通过资源所有者密码凭证认证,获取访问令牌
- 只在资源所有者和client高度可信的环境中使用
凭证模式(client credentials)
- client应用和可保护资源都在client应用的管理范围之内
- 没有前端的场景
访问令牌(Access Token)
- 使用访问令牌访问保护资源
- 访问令牌是client应用被资源所有者授权的凭证
- 访问令牌会在资源服务器和认证服务器使用
- 访问令牌是一种身份凭证,可以替代(username+passowrd)模式
- 访问令牌有有效期限
Refresh Token
- refresh token是获取access token的凭证
- 通过refresh token在access token失效或过期之前,获取新的access token
- 获取更小范围的scope
- 认证服务器访问refresh token是可选项
- refresh token不会发给资源服务器
刷新accesstoken:
+--------+ +---------------+ | |--(1)------- Authorization Grant --------->| | | | | | | |<-(2)----------- Access Token -------------| | | | & Refresh Token | | | | | | | | +----------+ | | | |--(3)---- Access Token ---->| | | | | | | | | | | |<-(4)- Protected Resource --| Resource | | Authorization | | Client | | Server | | Server | | |--(5)---- Access Token ---->| | | | | | | | | | | |<-(6)- Invalid Token Error -| | | | | | +----------+ | | | | | | | |--(7)----------- Refresh Token ----------->| | | | | | | |<-(8)----------- Access Token -------------| | +--------+ & Optional Refresh Token +---------------+
- client应用向认证服务器申请特定授权类型的访问令牌(access token)
- 认证服务器检查client应用和授权类型的有效性,如果有效,颁发访问令牌(access token)和刷新令牌(refresh token)
- client应用通过access token访问resource server端的保护资源
- resource server检查access token的有效性,如果有效,则允许访问
- 步骤3和4可以重复,直到访问令牌过期,如果令牌过期,则到步骤7
- 如果令牌失效,resource server会返回无效的token错误
- client应用通过refresh token申请新的access token
- 认证服务器检验client应用和refresh token的有效性,如果有效,则签发新的access token和新的refresh token
示意图
授权码模式
- 用户访问XX理财系统保护资源/private,在OAuth2.0流程中作为client应用角色
- 访问/private需要wechat认证用户,因此向wechat认证服务发起请求
上面 URL 中,response_type参数表示要求返回授权码(code),redirect_uri参数是接受或拒绝请求后的跳转网址,scope参数表示要求的授权范围
- 用户跳转后,认证服务会要求用户登录
- 询问是否同意给予 xx理财系统授权。用户表示同意,这时 会跳回redirect_uri参数指定的网址。
- {baseOrigin}/login/code/wechat?code=授权码授权码返回到XX理财系统
- 拿到授权码以后,就可以在后端,向 认证服务器请求访问令牌
- 授权码正确,返回访问令牌
- 获取访问令牌后,访问资源服务器,请求获取/userinfo接口
- 获取当前用户的授权信息,身份校验成功
- 允许访问/private
隐藏模式
- 申请授权
上面 URL 中,response_type参数为token,表示要求直接返回令牌
- 返回访问令牌
用户跳转到 认证中心登录页面,登录后同意给予 XX理财系统授权。这时,认证中心就会跳回redirect_uri参数指定的跳转网址,并且把令牌作为 URL 参数,传给 XX理财系统。
密码式
上面 URL 中,grant_type参数是授权方式,这里的password表示"密码式"
凭证式
不需要跳转,而是把令牌放在 JSON 数据里面,作为 HTTP 回应,A 因此拿到令牌。
凭证式
上面 URL 中,grant_type参数等于client_credentials表示采用凭证式,验证通过以后,直接返回令牌