OAuth2授权码模式详细流程(一)——站在OAuth2设计者的角度来理解code

本文来自于公众号链接: OAuth2授权码模式详细流程(一)——站在OAuth2设计者的角度来理解code

[图片上传失败...(image-74c76-1587020454879)])

​本文接上篇公众号文章《OAuth2核心协议概览》

大纲
概述

为什么要有授权模式

站在OAuth2设计者的角度来理解code

第一次实验:OAuth2 Client直接向用户要token
第二次实验:OAuth2 Client在后端直接向AS要token
第三次实验:OAuth2 Client在前端直接向AS要token
第四次实验:OAuth2 Client在前端向AS要code
总结与预告

概述
网上已经有很多介绍OAuth2授权码模式的文章了,也可以参考《最简洁实现Github登录的JS代码示例》。在OAuth2授权码模式流程中有还有很多使人迷惑的细节问题,本文就是回答其中几个与code相关的细节问题,如:
为什么要用户授权后,授权服务器才可以分发token?

为什么要先获取code,再用code交换token,直接获取token不行吗?

code为什么要设计为使用一次就失效?

我们将以全新的视角,站在OAuth2设计者的角度来理解code。
为什么要有授权模式
以《OAuth2核心协议概览》中的“朋友通过小区安保服务去我家里帮我拿东西”的现实场景来类比:
朋友找到小区安保服务,说要去我家拿东西(请求token)

安保电话询问我是否同意。朋友等待结果。

我告诉安保我同意。朋友还在等待结果。

安保挂断电话,允许朋友进入我家(获取到token)。

那OAuth2也完全照抄这个流程不就行了?就像这样:

可是关键的问题在于,web系统与现实场景是有区别的:
在web系统中,第一步请求token后,网络链接就关闭了,无法等待第四步token的返回。而一旦断开连接,Authorization Server就再也无法主动找到到OAuth2 Client,更不可能把token给到到OAuth2 Client了 。

web系统与现实生活例子最大区别就是web系统无法长时间等待:

Http协议是单向的无状态协议。只有浏览器端主动连接到服务器端,而服务器端是无法主动找到浏览器端的。

web系统的服务端要要同时支持无数浏览器端高并发,因此常规的Http的请求都是有超时限制的短链接,长时间不响应就会主动断开链接。

现实中获取token的流程不适合web系统,那么OAuth2协议是通过怎样的流程来绕过Http协议B/S架构的局限性,从而实现安全且相对高效地获取token的呢?
OAuth2把如何获取授权,从而获取token的这套流程称为“授权模式”。而其中最通用、最安全的流程叫做“授权码模式”。
站在OAuth2设计者的角度来理解授权码模式中的code
先不管OAuth2授权码模式详细流程是什么,我们假设自己就是OAuth2的设计者,现在要自己想办法实现安全、高效地获取token。
首先整个业务场景有四个角色:

Authorization Server认证服务器,简称AS

Resource Server资源服务器,简称RS

OAuth2 Client客户端,其他第三方服务

Resource Owner/User agent用户/用户代理,浏览器

其中的AS、RS和OAuth2 Client是web系统,而且OAuth2 Client和AS都必须有后端和前端。
我们要解决的是OAuth2 Client客户端如何获取token,然后使用这个token请求资源的问题。

第一次实验:OAuth2 Client直接向用户要token
是不是我们把问题想复杂了,OAuth2 Client 客户端直接跟用户要token不行吗?就像这样:

当然是不行的。用户哪里来的token?用户只有用户名和密码,而且是不能给你的。

第二次实验:OAuth2 Client在后端直接向AS要token
既然用户没有token,token是由AS颁发的,那最简单的方案不就是是那OAuth2 Client后端直接http请求AS的后端要token吗?就像这样:

这种流程也明显是不行的,因为AS首先要通知到用户,由用户亲自授权后,AS才能向OAuth2 Client发token。不经过用户授权就随便发token是明显地侵犯他人权益,不允许。
第三次实验:OAuth2 Client在前端直接向AS要token
那第一步请求获取token的操作就只能由OAuth2 Client的前端来发起了。
就像这样:

OAuth2 Client前端请求AS

AS返回一个交互页面,让用户确认是否授权

用户授权

到此AS已经获取到了用户授权,AS可以颁发token了。
此时面临的新问题是:AS如何把token给到OAuth2 Client?

经过分析,我只想到了两种方式:

方式一:直接给前端。虽然此时网络链接已经断开,但是AS仍然可以通过浏览器重定向的方式,将token作为URL参数传给到OAuth2 Client的前端。

方式二:直接给后端。AS直接调用OAuth2 Client后端的接口将token给到后端。但是先不说AS是否能直接调用 OAuth2 Client后端接口,就算可以调用, OAuth2 Client的后端也无法简单快捷地把获取token成功的状态通知到 OAuth2 Client前端和用户。

所以我们选择第一条路,通过浏览器重定向的方式将token给到 OAuth2 Client前端,OAuth2 Client前端再把token给OAuth2 Client后端就行了。
第四次实验:OAuth2 Client在前端向AS要code
虽然经过第三次实验后,OAuth2 Client 拿到了token。
可此时面临的新问题是:token直接暴露在浏览器地址栏了。
泄露token意味着直接泄露资源服务器中的数据。换句话说,token不应该出现在前端的任何地方。token只能在OAuth2 Client 、AS 和RS后端之间传递。

我实在想不出如何解决这个问题,但是OAuth2解决这个问题的方式非常巧妙,那就是引入code,这个code被称作“授权码”,这就是"授权码模式"名称的由来。具体的流程如图:

浏览器重定向不直接传token,而是先传一个code

OAuth2 Client前端拿到code,传给OAuth2 Client后端

OAuth2 Client后端携带这个code调用AS后端,AS校验成功后,放心地分发token。

为了安全,每一个code只能使用一次:AS一旦接收到携带这个code的请求,那这个code就作废了,不能使用同一个code再次请求了。同时,携带code交换token时,请求参数中需要携带OAuth2 Client的密钥。对于黑客来说,同一个code只能使用一次,还无法获取OAuth2 Client密钥,也就无法做token的暴力碰撞了。最重要的是:token一直在后端之间传递,根本就不给黑客通过浏览器窥视token的机会。

至此这就是完整的授权码模式流程。为什么要引入code来交换token的问题也就迎刃而解了。
总结与预告
OAuth2授权码模式完整流程图:

道高一尺魔高一丈,安全不是绝对的。假如token真的泄露了,那也比直接泄露用户名和密码强。因为:
token是有效期的,并且一般有效期很短,几秒钟到几分钟,短期的,到期就自动失效。

token可以被用户主动撤销而失效

token可以访问的数据是有权限控制的,是有限的权限。

这些OAuth2的细节设计都进一步增强了OAuth2协议的安全性。OAuth2协议也是非常灵活的协议,为了适应各种复杂的应用场景,除了授权码模式外,OAuth2还支持其他的授权模式,如密码模式、客户端模式和隐式授权码模式等等。另外授权码模式本身也还有很多细节问题,比如:
授权码模式中的scope到底都哪些用处,实现逻辑是怎样?

刷新token的逻辑怎么写才是正确的?

浏览器可以直接调用“/oauth/token”来获取token吗?为什么?

为什么一般的授权服务器的token接口都是禁止跨源访问的?

client_secret在获取code阶段需要传吗?

state参数到底有什么用,防止了哪些安全问题?

token本身是一个字符串,字符串本身可以是json格式数据吗?

token的有效期多长时间合适呢?

如何管理token的生命周期,token的格式是什么?

等等等等

这些话题都会在后续的文章里来讲解。
参考
OAuth2核心协议RFC 6749

更多干货都在《spring security实战》

本文来自于公众号链接: 彻底理解浏览器同源策略SOP
[图片上传失败...(image-b36771-1587020454879)])

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容