前言
OAuth2 目前一种 Web 主流的安全认证方法,是一种授权框架,资源所有者(Resource Owner)可以藉由授权伺服器(Authorization Server)来允许第三方应用程式(Client)来访问的受保护的资源(Protected Resource)。
co-author: MowLi 微风
OAuth 2.0
OAuth2规格书中,对资源也自定义的分配,下表为rfc中所分配的角色分配表:
举一个最常被 OAuth 相关书籍提及的例子:你(Resource Owner)有一张储存在云端服务的相片(Protected Resource),今天你想要透过一个影印服务(Client)去列印该相片。
在传统做法上,为了让影印服务(Client)拿到相片就必须将你的云端服务的凭证(例如:帐号密码)给这个影印服务,让它能存取该云端服务的资源。而 IETF RFC 6749 及 Action 书中列出了一些缺点:
Client 需要储存资源所有者的凭证,通常会是明文形式的密码Client 拥有过大对受保护资源的访问权限,而且资源所有者没有办法限制它访问时间或访问资源的範围资源所有者只能透过更改云端服务的密码来撤销影印服务的访问权限,而且没有办法只撤销一个(其它用到云端服务的 Client 应用程式都会受到影响)如果 Client 受到攻击,该攻击者还能存取受保护资源,以及资源拥有者其它使用相同密码的服务(很多人在不同网站都设同一组帐密)综观来说,在 OAuth2 中:
Client 必须先向 Resource Owner 请求授权来获得 Authorization Grant,这里面会包括 Client 能存取资源的範围。Client 藉由 Authorization Grant 向 Authorization Server 获取一个有时效性/永久性的 Access Token。以 Access Token 来存取 Protected Resource,而不是直接以 Resource Owner 的帐号密码来存取。简单来说,Client若要存取服务的话,首先要先拿到Authorization Grant,再使用Grant拿取Access Token,最后再使用Access Token存取服务。
Authorization Grant依照存取程度分为四种方式存取 Protected Resource:
Authorization Code
属于比较广泛被使用的,client 取得 Authorization Code 才能以此换取access token。
Implicit
是相对安全性来的稍微低一点,是直接取得 access token。好处是可以减少存取的 round trip 加速认证的过程。
Resource Owner Password Credentials Grant
指的是直接透过 password 直接从 Authorization Server 取得 access token,比较适合使用在可以信任的 client。
Client Credentials
完全信任 client,直接取得 token 直接存取 Protected Resource。
以 Authorization Server 角度而言,client 主要分为两种 confidential 与 public,就字面上意义 confidential 属于可以直接被信任的、public 属于不被信任的存取者。不被信任的 client 取得 Grant 的方式建议为:Authorization Grant、Implicit 的方式 ; 若是属于信任的 Client 建议为:Resource Owner Password Credentials Grant、Client Credentials。
public 指的是 Resource Owner 是属于一般使用者而非内部开发者,因此在进行取得凭证的过程应该使用较高的安全性的方式。confidential 指的是 Resource Owner 是属于内部开发者的,因为服务间会互相调用,因为是可信任的服务,因此用的凭证相对的比外部得来的宽鬆。
总结
OAuth 2 并不是专属给第三方程式存取认证模式,它本身是一种框架,适用任何的认证情况。事实上在 IETF RFC 文件中,针对不同的 client 有不同强度的认证方法。市面上主要广泛运用在存取第三方程式通常都以 Authorization Grant 的方式进行存取。然而 OAuth 2 其实也可以运用在内部 Service 自己存取时的场景!
参考资料
[1] Hardt, Dick. RFC 6749: The OAuth 2.0 Authorization Framework. Internet Engineering Task Force (IETF) 10 (2012): 2070–1721.