OAuth 2.0 —— 开放授权协议,对应的规范文件RFC-6749早在2012年便成形,所以这并不是一个新的技术(你问我为啥研究这个,我也想吟一首诗啊。。。组织上就是这样决定的),但由于其必不可少的价值,在今天的网络上已经得到了广泛的应用。

OAuth2.0认证是要在不同的应用之间打通互信,互信的目的是为了实现一定程度上的用户数据分享,没数据的一方到有数据的一方拿数据,并且在时间尺度上,数据的分享是受控的。

比如你在微信上打开小程序,小程序会向微信索要你的基本信息;比如你用马克飞象作为印象笔记的客户端,马克飞象会向印象笔记索要你的账户信息,以及阅读、创建、删除、修改笔记等的权限;比如你用github账号登录leetcode,后者会去前者索要你的账户信息 ……

在这些场景里都涉及三方:用户、没数据的应用、有数据的应用(授权、资源)。OAuth2.0规范就规定了三方如何交互,完成权限的授予,获取数据的过程。整体逻辑过程如下图

整个授权框架中包含了4种授权模式:

  • 授权码模式
  • 隐式许可模式
  • 密码模式
  • 客户端模式

在详述4种模式之前,首先需要注意,第三方应用需要先到资源持有应用处注册身份,提交回调URI,注册成功后,得到标识身份的 Client ID 和 Client Secret。资源持有者也可以趁这个阶段对第三方应用进行安全审核。

Client Type, 根据客户端与授权服务器进行安全认证的能力,分为 Confidential(机密客户端)和 Public(公开客户端)。
Client IDClient Secret,应用的身份标识。
Registered Redirect URIs,回调地址,后面会用到。

授权码模式

授权码模式是四种模式中最严密的,主要用于web应用,我们来看看整体逻辑图

下面我按图上的顺序一步步说明。

  1. 我在浏览器上打开了LeetCode网页,并且发现可以用github账户来登录,于是,我点击了章鱼标志。这个时候,就被LeetCode导向了github的认证页面,并且携带了几个必要参数。

    Client ID,表明第三方应用自己的身份,即这个请求是从LeetCode过来的。
    Scope,表明要请求哪些用户信息,用户名、密码、邮箱、头像……
    Redirect URI,应用注册时填入的回调URI之一,授权服务器会检查,必须严格匹配。
    State,一个不容意被猜到的随机数,用于第3步确认收到的code是自己请求的,避免 CSRF 攻击。

  2. 现在打开了github的认证页面(如果没有事先登录,github会要求我先登录github账号),github页面提示是否授权给LeetCode,点击是,则进入下一步;否则,流程结束。

  3. github调用回调URI(这个URI就是最初注册时提交的URI之一),传回授权码,把state也传回。这时,授权码就到了第三方应用的后台服务器。这一步之后的交互,在浏览器上就看不到了,由两个应用的后台服务器完成。

    Authorization Code,授权码,一个临时的随机串。
    State,第1步传过来的state。

  4. 拿到code,并比对了state后,LeetCode服务器就拿着这个code去换访问令牌。

    Client ID & Client Secret,表明自己的身份。
    Redirect URI,获取授权码时提交的回调地址,授权服务器会检查是不是一致。
    Authorization Code,前面拿到的授权码。

  5. 授权服务器认证了客户端身份,并检查回调地址通过后,调用回调URI回传访问令牌。

    Token Type,值为 Bearer Token。
    Access Token,访问令牌,访问资源的凭据。
    Scope,权限范围。
    Expires In,令牌有效时间,单位秒。
    Refresh Token,可选参数,用户更新访问令牌。

  6. 现在LeetCode可以拿着令牌去github获取我的账户信息了,从浏览器上看,我顺利登入了LeetCode。

回过头来看一下,为什么先发一个授权码,不直接发访问令牌?

因为直接发令牌,那么到达用户浏览器的就是令牌。而拿着令牌去访问资源是不需要认证的(别问为什么,就是这样的设计和用法)。如果本地环境不可信,那么让第三方应用服务器和资源服务器去交互,完成code到token的转换是更安全的选择。

即使Authorization Code被另一个应用窃取,并且该应用在授权服务器上合法,也不能使用这个授权码,因为授权服务器会检查带着授权码过来换token的应用是不是最初申请该授权码的应用。

而且,授权码只能被使用一次,当在本地被窃取了以后,如果你使用一次code,攻击者使用一次code,不管谁先谁后,第二次使用code将导致授权服务器终止该code及已下发的token的有效性。

授权码模式被使用的最多,以上讲解只是列出了规范中的主要参数,编码时具体实现还要看各厂是如何落地规范的,可以搜github、微信、google等的接口文档。

隐式许可模式

隐式许可模式和授权码模式最大的不同就是没有授权码交互这一环节,它主要用于依附于浏览器的驻于用户侧的应用,如JavaScript应用。

还是从图说起

  1. 和授权码模式一样。

  2. 和授权码模式一样。

  3. 用户授权通过后,调用回调URI,直接就传回访问令牌。

    Redirect URI,指向第三方应用的资源服务器。
    Fragment with Access Token, etc.,在URI的fragment部分(即#后的部分)携带访问令牌等参数,只会被留在浏览器本地,里面包含了和授权码模式第5步中相同参数。

  4. 访问第三方应用的资源服务器,请求从fragment参数中提取访问令牌的脚本,由于http规范,请求中不会携带fragment部分。

  5. 返回解析脚本,并提取出访问令牌。

  6. 拿着访问令牌去获取资源。

这里看到4、5的时候,困惑了很久,为什么要特地去第三方应用的服务器上取解析脚本,有什么安全考量。SO上某个5K声望的仁兄的回答是:没看出什么考虑,只是在本地放脚本和去服务器取脚本中选了一种方式。我看,是不是因为反正都会用到 Redirect URI,就顺便取个脚本,不然糟蹋了这一来一回。最后访问令牌留在了驻用户侧的应用里。考虑到这种模式不严瑾,行业最佳实践建议采用授权码模式或PKCE模式。

密码模式

密码模式就是用户把用户名和密码都放心地给到第三方应用(如山一般厚重的信任),第三方应用以用户的名字去认证并获取资源。规范中规定了应用不应该保存用户输入的用户名和密码。此种模式多见于资源服务器自家的应用。

客户端模式

第三方应用证明自己的身份,以自己的身份去获取一些公共的资源。这种模式我就不细解释了,参数用途和前面的一致。

基本就是这样了,下次再讲讲 PKCE、Device Code。

如理解有误,欢迎各位老铁拍砖。

参考:
https://oauth.net/2/
https://tools.ietf.org/html/rfc6749
https://getpocket.com/a/read/2216790858

认证授权那点事儿 —— OAuth 2.0相关推荐

  1. Spring Security OAuth2.0_实现分布式认证授权_集成测试_Spring Security OAuth2.0认证授权---springcloud工作笔记155

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后前面我们已经把分布式微服务的,认证授权全部集成了,然后我们来测试. 启动资源微服务order微 ...

  2. php授权验证系统 c,OAuth 2.0 授权码认证

    参考文章 组成成分 用户 应用1 应用2 流程 用户在应用1浏览.使用的过程中,涉及到要使用应用2功能的时候,就产生了 oauth 认证! A. 登录授权 应用1携带如下查询字符串: response ...

  3. 别再搞错!OAuth 2.0只是授权协议,OIDC才是认证授权协议

    上一文我们对Keycloak保护Spring Boot应用进行了实操.让大家见识到了Keycloak的强大.为了掌握Keycloak就必须对OpenID Connect(OIDC)协议进行了解. OI ...

  4. Spring Security OAuth2.0认证授权知识概括

    Spring Security OAuth2.0认证授权知识概括 安全框架基本概念 基于Session的认证方式 Spring Security简介 SpringSecurity详解 分布式系统认证方 ...

  5. SpringSecurity OAuth2.0认证授权-part2

    此篇文章包含oauth2项目搭建.整合jwt.授权方式测试: 篇幅过长,拆分为: part1: 认证授权原理回顾及分布式系统认证方案: part2: oauth2项目搭建.授权方式测试: part3: ...

  6. 基于go-oauth2/oauth2实现OAuth 2.0 授权码方式

    前言 本文基于go-oauth2/oauth2,参考go-oauth2/oauth2/example.go-oauth2/gin-server.llaoj/oauth2,结合beego框架实现OAut ...

  7. Spring Security——OAuth 2.0登录——Google,GitHub,Facebook和Okta

    基本概念 OAuth 2.0登录:OAuth 2.0登录功能为应用程序提供了使用户能够通过使用其在OAuth 2.0提供程序(例如GitHub)或OpenID Connect 1.0提供程序(例如Go ...

  8. OAuth 2.0实战(一)-通俗光速入门

    1 什么是开放平台(Open Platform) 在软件行业和网络中,开放平台指软件系统通过公开其API使外部程序可增加该软件系统的功能或使用该软件系统的资源,而无需更改该软件系统的源码. 在互联网时 ...

  9. OAuth 2.0 基础(2)

    为什么需要授权码? 在 OAuth 2.0 的体系里面有 4 种角色,按照官方的称呼它们分别是资源拥有者.客户端.授权服务和受保护资源.不过,这里的客户端,我更愿意称其为第三方软件,而且在咱们这个课程 ...

最新文章

  1. 【错误记录】Android Studio 向 GitHub 提交代码报错 ( Push failed: Failed with error: Could not read from remote )
  2. centeros php pgsql,centos php添加pgsql扩展
  3. vs2013下oracle proc配置
  4. linux 自启动程序 优先级,Linux自启动服务优先级/顺序设置
  5. 信息系统项目管理师论文指导(2/3)
  6. IOS开发-通知与消息机制
  7. 洛谷 - P4768 [NOI2018]归程(Kruskal重构树+树上倍增+最短路)
  8. 用PHP打印出前一天的时间
  9. java 调优参数 newRatio, survivorRatio
  10. python观察日志(part1)--字典反向查找
  11. C#-常用对象-思维导图
  12. Qt在指定区域内拖动窗口
  13. 通过实验理解交换的三个fast特性
  14. CSDN西安分站俱乐部聚会归来记
  15. pod镜像拉取策略、重启容器策略
  16. 中国无线充电行业发展规模与投资可行性咨询报告2022-2027年版
  17. create-react-app创建的项目配置多入口MPA模式。报Cannot read property ‘filter’ of undefined
  18. 名编辑电子杂志大师教程 | 隐藏不需要的功能按钮
  19. 全国青少年编程等级考试python一级真题2020年9月(含题库答题软件账号)
  20. Android 系统,Wifi连接后,显示wifi已连接但无法访问网络。

热门文章

  1. 如何从0到1搭建电商促销系统
  2. 快速创建ROS2 packages
  3. 票据ticket实现方式java代码_Java代码实践12306售票算法(二)
  4. 隐马尔可夫模型-三个盒子颜色序列概率计算问题
  5. MP | 东农吴凤芝/南农韦中-根系分泌物介导的植物种间互作塑造了根际微生物组抑病力...
  6. UVA 167 - The Sultan‘s Successors
  7. 动态表格中点击图片放大
  8. Java中的statis用法
  9. 菜鸟学示波器,示波器视频教程,ZLG示波器学习资料
  10. Python工程师是做什么的?如何学习Python