前言
这是笔者在日常工作学习中所总结的有关 OAuth 2.0 的系列文章之一;
OAuth 的标准所涵盖的概念较多,应用场景也较为复杂,所以,笔者打算撰写这样的一系列文章,来总结自己在日常工作和学习中所掌握的 OAuth 2.0 的相关概念和实践;
本文为作者的原创作品,转载需注明出处;
角色
为了能够理清相关的的概念,我们先要知道如下的一些有关 OAuth 的角色及其概念;
Client
从概念上而言,指一个“第三方的应用”;
比如你想授权“今日头条”应用来获取你的“新浪微博”上的身份信息和相关博文的信息,那么在该应用场景中,对于“新浪微博”而言,“今日头条”就是Client
,“新浪微博”同时扮演了Authorization Server 和 Resource Server 两个角色,而在这个过程中,你自己,作为该资源(既你的“新浪微博”上的身份信息和博文信息)的所有者,被称作 Resource Owner;从表现形式上而言,该 Client 可以是一个浏览器客户端、app 客户端、桌面应用等等;
从功能角色而言,Client 就是想获得 Resource Server 上的资源的这么一个角色;
Server
正如 Client 小节中所描述的那样,“新浪微博”就是扮演的 Server 的角色,可以看到,应用场景中,同时提供了“鉴权”和提供“资源”的功能;并且,由此分别对应两个角色,那就是 Authorization Server 和 Resource Server;
Authorization Server
从大多数的实现框架来说,比如 Spring OAuth Security,Authorization Server 有如下的功能,
- 对 Resource Owner 的身份进行验证;
- 颁发和验证 Authorization Code;
- 颁发和验证 Access Code;
注意,在一些划分的更为细致的架构中,会把该部分的功能定义到 Token Endpoint 上去完成;官网上是这么推荐的;但是大多数框架在实现的时候并没有分得如此的细; - 对第三方应用进行鉴权的作用;
说白了,就是验证 Client 是否有权限访问 [Resource Owner] 的资源以及访问的范围( Scope )和方式(只读、读写等),如果验证通过,则为 Client 发放通行证,也就是后面笔者将要介绍的 Access Token;
Token Endpoint
主要功能就是将 Access Token 的相关功能从 Authorization Server 中剥离出来;颁发和验证 Access Token;
Resource Server
Authorization Server 为 Client 发放通行证( Access Token ),Client 拿着该通行证去访问 Resource Server,当然 Resource Server 必须对该 Access Token 的有效性进行验证,比如是否通过,访问范围以及访问方式等等;
补充
通常,在没有使用微服务架构的情况下,通常 Authorization Server 既是鉴权服务器同时也是 Resource Server;
Resource Owner
故名思议,就是资源的拥有者,既是“用户”;
作用
OAuth 2.0 的作用是什么,通俗一点,就是它到底能干什么,能够解决什么样的问题?带着这两个问题,笔者梳理了下面两个小节;
待解决的问题
在 OAuth 协议出来以前,正如 Client 中所描述的场景那样,如果用户(Resource Owner)授权“今日头条”来获取自己在“新浪微博”中的个人账户信息或者是博客信息;那么只有将自己新浪微博的账户信息(用户名和密码)提供给“今日头条”,然后“今日头条”拿着用户的账户信息来登录“新浪微博”并获取用户相关的资源;这样就带来了一系列的问题;
- 用户的敏感账户信息泄露;
- 用户没有办法限制第三方 Client 既“今日头条”能够访问自己在“新浪微博”中的资源范围、方式和时效等等;
- 用户没有办法回收(Revoke)第三方的授权,除非修改密码,但是一旦修改,所有的之前被授权的 Client 将同时被收回授权;
使用 OAuth 如何解决
OAuth 协议正是为解决上述待解决的问题的背景之下而诞生的;解决的核心思路既是,如何让 Client 不在使用 Resource Owner 的用户名和密码的前提下,能够访问到用户在 Resource Server 上的被保护资源;于是,OAuth 2.0 采取了如下的措施,
- 客户端 Client 概念的重塑,
将用户的角色从 Client 的角色中分离出来,以前,Client 既是充当用户,同时充当 Client;为了区分这两个角色,所以,创建了 Resource Owner 这个角色; - 服务器端 Server 概念的重塑,
将以前单一的 Server 划分为 Authorization Server 和 Resource Server 两个角色; - 流程的重塑,
Resource Owner 通过 Authorization Server 授权第三方 Client 来访问自己在 Resource Server 上的被保护资源;其中授权是通过 Authorization Code 实现的,而访问资源的“权限验证”、“访问范围限制”以及“访问方式”的限制都是是通过 Access Token 来实现的;相关内容会在后面的内容进行详细的描述;
通过上述的一系列措施,Resource Owner 在授权第三方 Client 来访问自己在 Resource Server 上的资源的时候,就无需提供用户名和密码了,取而代之,只需要向 Client 提供临时的且随机生成的 Authorization Code 和 Access Token 即可,并且通过回收 Access Token 即可实现授权回收操作;
References
OAuth2 standard: https://tools.ietf.org/html/rfc6749
User agent: Hypertext Transfer Protocol: https://tools.ietf.org/html/rfc2616
CSRF, State:
https://github.com/pzxwhc/MineKnowContainer/issues/68
https://auth0.com/docs/protocols/oauth2/oauth-state
https://en.wikipedia.org/wiki/Cross-site_request_forgery