OAuth 2.0 授权框架(Authorization Framework)介绍
Open Authorization(OAuth)是一个开放、安全的协议。它通过引入授权层避免了第三方应用触及用户敏感信息的情况发生,并且可以更加容易的分别管理授权。也可以基于OAuth实现单点登录(SingleSignOn,SSO)。
一、角色(Roles)
OAuth定义了四个角色,依次如下:
资源所有者(Resource Owner)
能够为受保护的资源授予许可的实体。当资源所有者是一位人类(区别于机器)时被称为最终用户。
资源服务器(Resource Server)
托管受保护资源的服务器。该服务能够接受并使用访问令牌(access tokens)响应对受保护的资源的请求。
客户端(Client)
带着资源所有者的授权代表资源所有者去请求受保护的资源。这里的客户端是一个抽象概念,并不指代具体的客户端程序,它甚至也可以是一个服务端程序。客户端是一个相对的概念。
授权服务器(Authorization Server)
对资源所有者的凭据进行身份认证,如果成功则获得授权,并为客户端颁发访问令牌。
二、协议流(Protocol Flow)
(A) 客户端向资源所有者请求授权。
(B) 客户端收到表示资源所有者授权的凭据(可能是授权码、账号、客户端凭据)。
(C) 客户端携带资源所有者授权的凭据向授权服务器获取令牌。
(D) 授权服务器对客户端进行身份认证和授权,如果有效,则返回访问令牌。
(E) 客户端携带访问令牌请求资源服务器以获取受保护的资源,后者对前者进行身份验证。
(F) 资源服务器验证访问令牌,如果有效,则返回受保护的资源。
三、授权许可(Authorization Grant)
授权许可指的是资源所有者授予客户端的凭据。客户端可以使用该凭据来获取访问令牌。在规范中定义了四种凭据类型,如下:
授权码(Authorization Code)
客户端并不会直接向资源所有者请求授权,而是将资源所有者定向到授权服务器,授权服务器对资源所有者进行身份验证,如果验证通过则生成授权码,而后授权服务器再带上授权码将资源所有者定向回客户端。在上述流程中,授权服务器起到了中介作用,授权码也是通过该中介获取的。因为资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据永远不会与客户端共享。
隐式授权(Implicit)
隐式授权方式是简化的授权码方式,常常被用于在浏览器中使用脚本语言实现的客户端,例如JavaScript。在隐式授权中,授权服务器不再为客户端颁发授权码,而是直接向客户端颁发访问令牌。该过程中没有了授权码的参与,所以也称为隐式授权码。该方式多用在可能没有服务端的情况下。
需要注意的是,在隐式授权过程中,颁发访问令牌时,授权服务器不验证客户端。但为了安全,有时候可能会采用重定向URI的方式传递回访问令牌,被重定向的URI可以验证客户端身份是否合法。隐式授权方式虽然提高了效率,但却牺牲了部分安全性,在使用时需要权衡。
密码模式(Resource Owner Password Credentials)
资源所有者的密码凭据(可能是用户名和密码)可以直接用作获取访问令牌的凭据。仅当资源所有者和客户端之间具有彼此高度信任时,或当其它授权类型不可用时,才应考虑使用该种授权方式。
尽管该授权类型会使客户端直接访问资源所有者的凭据,但资源所有者的凭据可能仅用于单个请求并交换为访问令牌。这种授权类型可以通过与长期访问令牌或刷新令牌交换凭据,从而避免客户端为将来可能使用资源所有者凭据而将其存储。
客户端凭据(Client Credentials)
当授权范围是客户端控制下的受保护资源,或是与授权服务器约定的受保护资源时,客户端凭据(或其它形式的客户端身份验证)可用作授权许可。
四、访问令牌(Access Token)
访问令牌是带有特定访问范围和持续时间的用以访问受保护资源的凭据,它是颁发给客户端用以检索授权信息的标识符,以可验证的方式(由数据和签名组成的令牌字符串)自包含授权信息。对于客户端来说,该字符串通常是不透明的。令牌由资源所有者授予,并由资源服务器和授权服务器强制执行。
访问令牌提供了一个抽象层,用资源服务器能够处理的令牌代替不同的授权结构(例如用户名和密码),从而避免了资源服务器兼容处理各种身份验证的情况。根据资源服务器安全要求,访问令牌可以具有不同的格式、结构和使用方法(例如,加密属性)。
五、刷新令牌(Refresh Token)
刷新令牌是由授权服务器颁发给客户端的,用以在当前访问令牌无效或过期时获取新的访问令牌的凭据,或获取具有相同或更小范围的其它访问令牌(访问令牌的生存期可能比资源所有者授权的短,权限也可能更少)的凭据。颁发刷新令牌是可选的,一般根据授权服务器的判断来决定是否需要刷新令牌。如果授权服务器颁发了一个刷新令牌,那么在颁发一个访问令牌的同时就会包含刷新令牌。
刷新令牌是资源所有者授予客户端的,用于检索授权信息的标识符。对于客户端来说,该标识符通常是不透明的。与访问令牌不同,刷新令牌仅用于授权服务器,不会发送到资源服务器。协议流如下:
(A)客户端向授权服务器提供凭据进行身份验证以获取访问令牌;
(B)授权服务器验证通过后,为客户端颁发访问令牌和刷新令牌;
(C)客户端携带访问令牌向资源服务器请求受保护的资源;
(D)资源服务器验证访问令牌是否有效,如果有效,则返回受保护的资源;
(E)重复步骤(C)和(D),直到访问令牌过期。如果客户端知道访问令牌已过期,它将跳到步骤(G);否则,它将请求另一个受保护的资源;
(F)由于访问令牌无效,资源服务器会返回一个无效令牌的错误;
(G)客户端携带刷新令牌请求授权服务器以获得新访问令牌;
(H)授权服务器对客户端身份以及刷新令牌做验证,如果有效,则颁发新的访问令牌,以及可选的新的刷新令牌。
六、HTTP重定向(HTTP Redirections)
基于OAuth2.0的规范广泛使用了HTTP重定向,任何其它的可通过用户代理完成此重定向的方法都是被允许的,并同样被视为实现细节。
七、互操作性(Interoperability)
OAuth 2.0以其良好的安全属性提供了丰富的授权框架。 但是,作为一个具有许多可选组件的,丰富且高度可扩展的框架,在此规范的约束下,可能会产生各种不可互操作的实现。
另外该规范对于一些必要组件的定义是不完整的,例如,客户端注册,授权服务器功能,端点发现等。如果没有这些组件,则必须针对特定的授权服务器和资源服务器手动和专门配置客户端,以便进行互操作。
八、术语约定(Notational Conventions)
与安全性相关的术语包括但不限于“攻击(attack)”,“身份验/认证(authentication)”,“授权(authorization)”,“证书(certificate)”,“机/保密(confidentiality)”,“凭证(credential)”,“加密(encryption)”,“身份(identity)”,“签名(sign,动词,例如sign in)”,“签名(signature,名词)”,“信任(trust)”,“验证(validate,复杂)”和“验证(verify,简单)”。除非另有说明,否则所有协议参数名称和值区分大小写。
说明:文中多次提到“凭据”,“凭据”并不是某个过程或节点独有的,理解“凭据”需要结合上下文环境,比如资源所有者的“凭据”可能是用户输入的用户名和密码,服务器的“凭据”可能是服务与服务之间交换信息的“授权许可”。
参考:http://www.rfcreader.com/#rfc6749