OAuth 是 Open Authorization 简称,是一个开放授权协议,允许WEB应用、移动应用和桌面应用进行安全授权。
OAuth 允许资源所有者授权第三方应用访问其在服务提供商的特定私有资源,整个过程不需要提供账号和密码给第三方应用。
目前应用最广泛的是 OAuth 2.0, OAuth 1.0
版本已经废弃,OAuth 2.1 还在进行中。通常我们所说的 OAuth 指的就是 OAuth 2.0 。
核心概念
OAuth 协议并不是一个单一文本格式,而是一套多个角色进行交互完整的流程,所以我们先把角色和流程相关的概念理解清楚。
角色相关概念
资源所有者,通常指的是用户。该用户将私有资源保存在服务提供商,通过由服务提供商提供的用户名和密码验证资源所有者的身份。用户输入用户名和密码通过服务提供商验证就能获取私有资源。这样在第三方应用中不需要单独保存用户名和密码,
第三方应用,又称为客户端,此客户端是相对于服务提供商而言,即服务提供商的客户端,客户端需要在服务提供商提前注册。客户端可以是任何类型的应用程序,比如:WEB应用程序、移动应用程序、桌面应用程序。第三方应用可以共享服务提供商的用户,这样在第三方应用中不需要单独保存用户名和密码,
服务提供商,提供授权服务和资源服务。授权服务负责验证用户是否同意授权,发放和验证访问令牌;资源服务为资源所有者提供服务,例如:保存用户信息。授权服务获得用户同意授权之后发放访问令牌,每一个令牌授权一个特定的客户端在特定的时段内访问特定的用户资源。
资源服务,通常以 Web API 方式提供;授权服务,Authorization Server 简称 AS,授权服务负责对资源服务的访问授权。
用户代理,对于WEB应用通常指的是浏览器;移动应用指的是APP根据用户操作发送HTTP请求。用户通过浏览器发送请求,浏览器“代表”用户。
流程相关概念
重定向Url(Redirect Url):服务提供商通过重定向Url验证第三方应用是否合法,并将要发送的信息重定向到第三方应用。重定向Url在服务提供商注册应用程序时设置,这样可以有效防止伪造请求攻击。重定向Url推荐使用TLS协议确保信息安全,防止在授权过程中信息被截取。
终结点(Endpoint),请求到达的终点,一个 Uri ,比如:授权服务器提供的令牌终结点,响应请求,返回令牌;授权终结点,响应请求,显示授权页面。
前端通道(Front Channel),信息通过 Uri或 Form Post 传递到浏览器,通常与授权终结点交互。
后端通道(Back Channel),信息通过服务器到服务器之间进行通信,通常与令牌终结点交互。
授权类型,在 OAuth 2.0 核心规范中,定义了多种授权类型,授权类型在其他的部分文档中又被称为“授权流程”、“授权模式”或“标准流程”,为了更加准确表达,教程中统一使用授权类型。
访问令牌(Access Token):也叫
token
,用来访问被保护资源的凭据,是一个字符串,代表给客户端颁发的授权,其中包含描述资源所有者授予的访问权限的范围和持续时间。为了安全,通常对客户端应用是不透明的,也就是说客户端无需查看(无法解析令牌,验证服务器验证)。客户端的任务就是把它展示给被保护的资源。授权服务器的任务只是发行该令牌,而被保护资源的任务是验证该令牌,所以它们都必须理解访问令牌的构成,并知道访问令牌包含的授权内容。授权范围(Scopes):又称作用域,表示被对保护资源的访问权限,用区分大小写的字符串表示,用空格作为分隔符来表示多个授权范围。这些表示授权范围的字符串由授权服务器来定义,而授权范围字符串的格式和结构在 OAuth 2.0 里并没有定义,所以可以自定义。授权范围的作用是限制客户端应用的访问权限,客户端应用可以请求授权服务器授予指定授权范围,授权服务器允许资源所有者获取或拒绝特定的授权范围。
刷新令牌(Refresh Token):用来获得新的访问令牌(Access Token)凭据,和 acces token 差不多,refresh token也是由授权服务器发行给客户端应用的,refresh token 是在发行 access token 一同返回的。客户端不知道也不关心refresh token里面有啥,refresh token不会被发送给被保护的资源,仅用于客户端用 refresh token 来请求新的 access token ,尤其是当现在的 access token 过期或者失效时,但这个过程就不需要资源所有者的参与了,Refresh Token是可选的。
基本原理
OAuth 协议要解决第三方应用征得资源所有者同意之后安全地访问服务提供商提供的私有资源的问题。
以下是 OAuth 通用流程示意图:
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
OAuth 2.0 协议流程 (A)客户端向资源所有者发起授权请求 (B)客户端收到授权凭证(和具体的授权类型有关) (C)客户端通过授权凭证向授权服务器请求访问令牌 (D)授权服务器验证授权凭证和客户端,如果通过验证,返回给客户端访问令牌 (E)客户端通过访问令牌向资源服务器发出访问请求 (F)资源服务器验证访问令牌有效后,返回请求的资源
客户端可以向资源所有者直接发起授权请求(密码凭证授权,用户登陆输入用户名和密码),但是建议的做法是将授权服务器作为中间人,由客户端向授权服务器发起授权请求。
以上流程可以简化为两个核心步骤:
- 第一步:获取授权码,服务提供商询问用户是否同意授权,用户同意授权,给客户端发放授权码。(非必须)
- 第二步:获取访问令牌,服务提供商根据客户端携带授权码及客户端标识进行客户端验证,客户端验证成功,发放供客户端访问服务提供商受保护资源的访问令牌。
OAuth 已经在各大公司广为应用,例如:
- 第三方登陆(QQ登陆、微信扫描登陆)
- 开放平台(微信开放平台、支付宝开放平台)
微信开放平台或者支付宝开放平台是 Auth 2.0 服务提供商,开发者需要登陆开放平台为要使用开放平台的应用程序先进行注册,设置应用名称、网址、logo、回调地址等信息。应用程序注册好之后,服务提供商会为每个应用分配一个 Client Id 和一个 Client Secret,Client Id是公开信息,用来构建登陆Uri ;Client Secret是私密信息,用于服务提供商验证应用是否是合法的客户端。
授权类型
OAuth 2.0 协议定义了四种授权类型:
- 授权码授权(Authorization Code Grant)
- 密码凭证授权(Resource Owner Password Credentials Grant)
- 客户端凭证授权(Client Credentials Grant)
- 隐式授权(Implicit Grant)
接下来详细解析每一种授权类型。