您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

一文搞懂OAuth2.0授权协议是怎么回事

时间:2022-03-11 16:07:56  来源:  作者:一一哥Sun

前言

截止到现在,一一哥 已经带各位把Spring Security中的主要功能学完了,并且剖析了这些内容的底层实现原理,希望你可以有所收获。

但是在安全认证领域,还有另一种很重要的授权机制---OAuth2.0开放授权。而且OAuth2.0开放授权与Spring Security经常配合使用,这两者之间可以说是“焦不离孟,孟不离焦”的搭配关系,所以为了进一步掌握Spring Security,在这里 壹哥 给大家再介绍另一个OAuth2.0开放授权协议。

OAuth2.0开放授权并不是Spring Security框架里的一部分,只是两者经常配合使用而已,所以我得先给大家普及一下OAuth2.0的内容,毕竟OAuth2.0的内容还是蛮难理解的。

一. OAuth2.0简介

1. OAuth2.0概述

咱们先来看看在RFC6749号文件中对OAuth2.0的定义,如下图所示:

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

简单来说,OAuth2.0 是一种授权机制,其内部引入了一个授权层,可以分离两种不同的角色:客户端和资源所有者。资源所有者同意客户端(第三方应用程序)的请求以后,资源服务器就可以向客户端颁发短期的进入令牌(token),用来代替密码,客户端通过这个令牌,去请求有限的资源数据来使用。所以OAuth2.0 的核心就是向第三方应用颁发令牌。

2. OAuth2.0发展历程

OAuth(Open Authorization)--开放授权,这是一种关于开放授权的协议标准。所谓的OAuth2.0,表示这是OAuth协议第2版,但并不兼容之前的OAuth1.0协议,即现在已经完全废止了OAuth1.0协议。

那么为什么会废止OAuth1.0协议呢?我们先来简单说一下OAuth协议的发展历程。

2007年12月的时候,OAuth协议已经诞生了,并与2010年4月份,被IETF(国际互联网工程任务组)认可并作为认证授权的标准发布。但是这个OAuth1.0协议有些致命缺陷,就是它的签名逻辑特别复杂,开发时对程序员来说极度恶心。而且OAuth1.0的授权流程是很单一,存在较大的漏洞,容易被黑客攻击。所以在2012年10月的时候,IETF又更新发布了OAuth2.0协议,在这个版本中,放弃了之前复杂的数字签名和加密方案,使用HTTPS来作为安全保障手段,这降低了程序员的开发难度。但是OAuth2.0协议与OAuth1.0协议互不兼容,所以现在我们进行开发时,都是采用OAuth2.0协议,而不再采用OAuth1.0协议。

3. OAuth2.0功能

通过上一小节,我们了解到OAuth是一种关于开放授权的协议,该协议其实是一个 服务提供商 授权 第三方应用 获取 资源所有者 部分访问权限 的授权机制。通俗的说,就是OAuth协议允许用户在不提供密码给第三方应用的情况下,使得第三方应用有权获取用户数据等基本信息。在整个授权过程中,第三方应用都不必获取用户的密码,就可以取得用户部分资源的使用权限,所以OAuth是一种安全开发的协议。

比如我们在CSDN上进行登录时,可以利用CSDN这个平台自身注册的账号,也可以使用第三方账号(QQ、微信、微博等)来进行登录,如下图:

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

比如我们选择利用QQ账号登录CSDN,如下图:

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

这时候我们可以打开QQ扫码,或者点击自己的QQ头像,就可以实现利用QQ帐号登录到CSDN这个网站上。在这个过程中,我们其实不必担心自己的QQ密码会泄露给CSDN,因为CSDN是拿不到我们的QQ密码的。

在这个登录过程中,CSDN相对于QQ来说是第三方应用,QQ就是服务提供商。在QQ内部,会有一个认证服务器作为专门的授权中心,QQ用户的用户名头像等信息都属于资源,这些资源可能会存放在一台专门的资源服务器上,也可能会直接存放在QQ的认证服务器上。当CSDN经过了QQ的认证之后,就可以获取到QQ上的用户昵称、头像、性别等信息,从而实现利用QQ的用户,登录到CSDN的网站上,免除用户重复的注册过程。

4. OAuth2.0使用场景

根据上一小节,我们可以总结一下OAuth2.0的使用场景,大致如下:

  • 第三方应用登录:比如利用QQ,微博,微信授权登录到其他网站或App
  • 分布式或微服务项目中授权:JAVA分布式或微服务开发时,后端业务拆分成若干服务,服务之间或前端进行请求调用时,为了安全认证,可以利用OAuth2.0进行认证授权。

二. OAuth2.0核心概念(重点)

1. 核心概念

另外从上面的章节中,我们也了解到OAuth2.0的几个核心概念,如下:

  • 客户端/第三方应用: 获取用户信息,如果我们使用QQ账号来登录CSDN网站,这时候CSDN相对于QQ来说就是第三方应用,或者成为是QQ的客户端。
  • 服务提供商: 对外提供请求的服务器,比如上面说的QQ。
  • Resource Owner:资源所有(拥有)者,首先我们要明确“资源”的含义,“资源”是指我们请求的各种URL接口及各种数据,这里的资源所有者,也就是登录用户。
  • Authorization Server:认证服务器,即服务提供商(比如QQ)专门用来处理认证的服务器。
  • Resource Server:资源服务器,即服务提供商存放用户资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。
  • Access token: 访问令牌,供客户端用来请求Resource Server(API)的资源,Access token通常是short-lived短暂的。

2. 令牌与密码

在OAuth2.0中,提到了一个令牌的概念,那么令牌是什么?与我们平常所用的密码又有什么区别?其实OAuth中的令牌(token)与密码(password)作用是一样的,都可以控制用户是否可以进入系统,但是有几点不同。

  • 令牌是短期的,到期后会自动失效,用户自己无法修改;密码一般是长期有效的,用户不修改,就不会发生变化。
  • 令牌可以被资源所有者撤销,立即失效;密码一般不允许被他人撤销。
  • 令牌有一定的授权范围(scope),密码一般是完整权限。

注意:

令牌的出现,既可以让第三方应用获得权限,同时又可以随时可控,不会危及系统安全。但是只要知道了令牌,就能进入系统,系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。这也是为什么令牌的有效期,一般都设置得很短的原因。

三. OAuth2.0授权流程(重点)

了解完OAuth2.0中的各种基本概念之后,我们需要弄清楚OAuth2.0的授权流程,这样后面才能根据这个授权流程进行开发。

1. 授权流程概述

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

OAuth 2.0的运行流程如下图,摘自RFC 6749。

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

我们这里以QQ账号登录CSDN网站为例,给大家说一下OAuth2.0的授权执行流程:

(A). 某个用户(资源拥有者)打开CSDN(客户端)网站以后,CSDN(客户端)要求用户(资源拥有者)给予授权;
(B). 如果用户(资源拥有者)同意,就给予CSDN(客户端)授权;
(C). CSDN(客户端)使用上一步获得的授权,向QQ的认证授权服务器申请访问令牌Access Token;
(D). QQ的认证授权服务器对CSDN(客户端)进行认证,确认无误后,同意发放访问令牌Access Token;
(E). CSDN(客户端)使用访问令牌,向QQ的资源服务器申请获取某些受保护的资源;
(F). QQ的资源服务器确认访问令牌无误后,同意向CSDN(客户端)开放受保护的资源。

2. 授权流程详解

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

第一步:在CSDN官网点击选择QQ登录

当我们点击选择QQ登录的图标时,实际上是向CSDN服务器发起了一个

https://graph.qq.com/oauth2.0/show?which=Login&display=pc...&response_type=code&redirect_uri=https....passport.csdn.NETogin%3FpcAuth...Type=qq的请求,CSDN服务器会响应一个302重定向地址,指向QQ授权登录。这次访问会携带一个pcAuthCallback,以便QQ那边授权成功后,再次让浏览器发起对这个callback的请求,这样QQ就知道授权后要返回到哪个页面。

第二步:跳转到QQ登录页面输入用户名密码,然后点授权并登录

接着浏览器跳转到重定向地址并访问 http://www.qq.com/authorize?callback=https://yiyige.blog.csdn.net/,QQ的服务器接受到了CSDN访问的authorize,并跳转到QQ的登录页面。在用户输入账号密码点击授权并点击登录按钮后,QQ的认证服务器会对用户信息进行认证,若校验成功,该方法会响应浏览器一个重定向地址,并附上一个code(授权码)

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

第三步:跳回到CSDN页面,登录成功

这一步背后的过程其实是最繁琐的,但对于用户来说是完全感知不到的。

授权QQ服务器在判断登录成功后,使页面重定向到之前CSDN发来的callback地址并附上code授权码,接着会跳转到QQ的认证服务器发起一个新的请求,获取到AccessToken令牌。获取token成功后,CSDN服务器会用拿到的token换取用户信息,最后将用户信息储存起来,并返回给浏览器其首页的视图,到此OAuth2.0授权结束。

四. OAuth2.0授权方式(重点)

讲解完了OAuth2.0的授权流程,接下来壹哥再给大家介绍另一个重要概念,即OAuth2.0的授权方式。

在RFC 6749标准中定义了获得令牌的四种授权方式(authorization grant),即 OAuth2.0 有四种获得令牌的方式,我们开发时可以选择最适合自己的那一种,向第三方应用颁发令牌,这四种授权方式如下:

  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

1. 授权码模式

授权码模式(authorization code),指的是第三方应用先申请一个授权码,然后再用该授权码获取访问令牌的方式。这种方式是功能最完整、流程最严密的授权模式,也是开发时最常用,安全性最高的授权模式,适用于那些有后端的 Web 应用,比如我们前面介绍的以QQ信息登录到CSDN网站上就是采用授权码模式。授权码由前端发起申请,令牌则储存在后端,而且所有与资源服务器的通信都在后端完成,这样前后端分离,可以避免令牌泄漏。授权码模式执行流程可以分为如下4步:

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

接下来我把这4步再分开详细说明一下。

(1). 用户请求客户端A,

由客户端A将用户导向认证服务器B请求授权码,假设用户同意授权,认证服务器B会将用户导向客户端A事先指定的"重定向URI"(redirection URI),同时附上一个授权码。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

比如我们前面利用QQ进行登录到CSDN网站时,获取code授权码的url:

https://graph.qq.com/oauth2.0/show?which=Login
    &display=pc
    &client_id=100270988899
    &response_type=code
    &redirect_uri=https://passport.csdn.net/account/login?pcAuthType=qq
    &state=test
  • response_type:授权类型,必选项,为固定值code;
  • client_id: 客户端id,必选项,表示告诉 认证服务器B 是谁在发起请求;
  • redirect_uri:可选项,是 认证服务器B 接受或拒绝请求后的回调网址;
  • scope:可选项,表示要求的授权范围(这里是只读);
  • state: 客户端状态。

(2). 客户端A收到授权码code,

附上之前的"重定向URI"参数,向认证服务器B申请令牌:GET /oauth/token?response_type=code&client_id=test&redirect_uri=重定向页面链接,请求成功后返回code授权码,一般有效时间是10分钟。

https://a.com/callback?code=AUTHORIZATION_CODE

(3). 客户端A向认证服务器B发起申请令牌的请求,

B会核对授权码和重定向URI,确认无误后,向客户端A返回访问令牌(access token)和更新令牌(refresh token),POST /oauth/token?response_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=重定向页面链接。

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

(4). 认证服务器B 收到请求以后,

就会颁发令牌,向redirect_uri指定的网址,发送一段 JSON 数据:

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

2. 简化模式

简化模式(implicit grant type),有些 Web 应用只有前端,没有后端,这时就只能将令牌储存在前端浏览器中。所以在RFC 6749中还规定了第二种授权方式,允许直接向前端颁发令牌,因为是直接在浏览器中向认证服务器申请令牌,跳过了"授权码"这个步骤,所以称为 "隐藏(授权码)式implicit",或者被称为隐式授权模式。

隐式授权模式的客户端一般是指用户浏览器,访问令牌通过重定向的方式传递到用户浏览器中,再通过浏览器的JavaScript代码来获取访问令牌。这种授权方式的所有步骤都是在浏览器中完成,没有通过第三方应用程序的服务器,访问令牌直接暴露在浏览器端,令牌对访问者是可见的,且客户端不需要认证,所以可能会导致访问令牌被黑客获取。该模式适用于对安全性要求不高的应用中,仅适用于需要临时访问的场景。

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

流程步骤:

(A). 客户端将用户导向认证服务器;
(B). 用户决定是否给于客户端授权;
(C). 假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌;
(D). 浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值;
(E). 资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌;
(F). 浏览器执行上一步获得的脚本,提取出令牌;
(G). 浏览器将令牌发给客户端。

请求URL:

GET /authorize?response_type=token&client_id=s6BhdRkqt3
    &state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb 
    
HTTP/1.1

Host: server.example.com 

与授权码模式相比,用户的登录环节是一样的,只是在授权成功之后的重定向上,授权码模式是携带一个认证码,由客户端通过认证码申请访问令牌。而隐式授权模式则直接将访问令牌作为URL的散列部分传递给浏览器,散列部分是专门用于指导浏览器行为的,比如浏览器页面定位的锚点就可以由散列属性来进行判定。

注意

简化授权方式是把令牌直接传递给前端,这是很不安全的。因此,该授权方式适用于一些对安全性要求不高的场景,并且令牌的有效期必须非常短,通常是在会话期间(session)有效,当浏览器关掉,令牌就失效了。

3. 用户名密码模式

密码模式(Resource Owner Password Credentials Grant),客户端提供一个专用页面,然后用户向客户端提供自己的用户名和密码,客户端使用这些信息,向"服务提供商"索要授权。在这种模式中,用户必须把自己的用户名密码给客户端,但是客户端不得存储密码。该授权模式适用于用户对客户端高度信任的情况下使用,一般不支持refresh token。

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

执行步骤:

(A). 用户向客户端提供用户名和密码;
(B). 客户端将用户名和密码发给认证服务器,向后者请求令牌;
(C). 认证服务器确认无误后,向客户端提供访问令牌;

响应信息:

POST /token HTTP/1.1 
Host: server.example.com      
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW      
Content-Type: application/x-www-form-urlencoded  
grant_type=password&username=johndoe&password=A3ddj3w

注意

用户名密码授权方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

4. 客户端模式

客户端模式,指客户端以自己的名义,而不是以用户的名义,向"服务提供商"发起认证。严格地说,客户端模式并不属于OAuth2.0框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求"服务提供商"提供服务,其实不存在授权问题。

客户端授权模式通常是由客户端提前向授权服务器申请应用公钥、私钥,并通过这些关键信息向授权服务器申请访问令牌,从而得到资源服务器提供的资源,比如常见的微信公众平台、支付宝支付平台授权等。该模式适用于没有前端的命令行应用中,即在命令行下请求令牌。

赞!一文搞懂OAuth2.0授权协议是怎么回事

 

执行步骤:

(A). 客户端向认证服务器发起身份认证,并要求一个访问令牌;
(B). 认证服务器确认无误后,向客户端提供访问令牌。

A步骤中,客户端发出的HTTP请求,包含以下参数:

  • granttype:表示授权类型,此处的值固定为"clientcredentials",必选项。
  • scope:表示权限范围,可选项。

响应信息:

POST /token HTTP/1.1
Host: server.example.com

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

#grant_type参数等于client_credentials表示采用凭证式,
#client_id和client_secret用来让 B 确认 A 的身份

注意

这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

希望通过本文的介绍,可以让你对OAuth2.0协议有所掌握,后面我们可以把Spring Security与OAuth2.0结合,实现更灵活的认证授权。

若本文可以让你有所收获,请给壹哥点个赞吧!



Tags:OAuth2.0   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
一文搞懂OAuth2.0授权协议是怎么回事
前言截止到现在,一一哥 已经带各位把Spring Security中的主要功能学完了,并且剖析了这些内容的底层实现原理,希望你可以有所收获。但是在安全认证领域,还有另一种很重要的授权机...【详细内容】
2022-03-11  Search: OAuth2.0  点击:(366)  评论:(0)  加入收藏
带你全面了解 OAuth2.0
最开始接触 OAuth2.0 的时候,经常将它和 SSO单点登录搞混。后来因为工作需要,在项目中实现了一套SSO,通过对SSO的逐渐了解,也把它和OAuth2.0区分开了。所以当时自己也整理了一篇...【详细内容】
2021-09-16  Search: OAuth2.0  点击:(286)  评论:(0)  加入收藏
OAuth2.0分布式系统环境搭建
介绍OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。OAuth...【详细内容】
2020-08-18  Search: OAuth2.0  点击:(361)  评论:(0)  加入收藏
你真的理解OAuth2.0协议吗?深入解读OAuth2.0协议
从事互联网开发的同学们应该或多或少听说过 OAuth2.0 协议,例如使用微信或支付宝账户登录第三方App,这是 OAuth2.0 最为开发人员所熟知的一个用途,但是围绕着 OAuth2.0 协议其...【详细内容】
2020-07-12  Search: OAuth2.0  点击:(422)  评论:(0)  加入收藏
学习一下OAuth2.0协议
一、什么是OAuth协议OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 OAuth的授权不会使第三方触及到用户的帐号信息(如用户...【详细内容】
2019-08-01  Search: OAuth2.0  点击:(1130)  评论:(0)  加入收藏
▌简易百科推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  步步运维步步坑    Tags:架构   点击:(6)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27    InfoQ  Tags:架构模式   点击:(16)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  哈啰技术  微信公众号  Tags:架构   点击:(12)  评论:(0)  加入收藏
DDD 与 CQRS 才是黄金组合
在日常工作中,你是否也遇到过下面几种情况: 使用一个已有接口进行业务开发,上线后出现严重的性能问题,被老板当众质疑:“你为什么不使用缓存接口,这个接口全部走数据库,这怎么能扛...【详细内容】
2024-03-27  dbaplus社群    Tags:DDD   点击:(15)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13    阿里云开发者  Tags:高并发   点击:(8)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  二进制跳动  微信公众号  Tags:架构设计   点击:(38)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  ijunfu  今日头条  Tags:SpringBoot   点击:(21)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  547蓝色星球    Tags:架构   点击:(121)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11    王建立  Tags:Spring Boot   点击:(128)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  互联网架构小马哥    Tags:Spring Boot   点击:(127)  评论:(0)  加入收藏
站内最新
站内热门
站内头条