> 技术文档 > 小白入门一文通-安全专题2- OAuth2.0 一次搞明白!_oauth2.0认证原理

小白入门一文通-安全专题2- OAuth2.0 一次搞明白!_oauth2.0认证原理


系列文章目录

《小白入门一文通》为一个技术专题频道,目的旨在通过尽量入门基础的语言,描述业界的基础理论,方便小白快速上手理解,初步规划:安全、网络、编码等专题,可通过标题快速筛选浏览,希望我们可以一起从小白快速成长为高手!


目录

系列文章目录

目录

前言

一、OAuth 2.0原理

1、核心逻辑

2、OAuth2.0四种授权方式

授权码方式

隐藏式

密码式

凭证式

二、OAuth关联核心名词概念

1. OIDC(OpenID Connect)

2.  SSO(单点登录)

总结


前言

随着人工智能的不断发展,涉及不同Agent之间相互发现、调用是必经的一个流程,涉及安全层面最核心的就是认证、鉴权、授权,而授权的核心安全实现当前主流就是基于OAuth2.0 及 VC&VP技术,整体大的趋势是基于当前OAuth机制扩展,本文先介绍其一Oauth2.0的核心原理,便于理解后续Agent的授权新机制扩展。


一、OAuth 2.0原理

OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容。OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth1.0即完全废止了OAuth1.0。OAUTH是一种开放的协议,为桌面、手机或web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。

授权码(authorization-code)
隐式(implicit)
密码式(password)
客户端凭证(client credentials)

注意,不管其定义的4种授权方式,第三方应用申请令牌之前,都必须先到授权服务器备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。相当于账号密码,这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。比如:微信登录第三方应用,需要先在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的 AppID 和 AppSecret。(核心前提,重点理解,也就是微信首先要与第三方应用,要先签订互通协议),这也就决定了Oauth中的关键字段Scope的用法,举例说明:

Scope用于限制第三方应用可以获取哪些用户账户信息,由微信授权服务器自己定义。 第三方应用可以请求一个或多个scope,然后在在授权页面把申请的微信账户权限范围呈现给用户,并且颁发给该第三方应用的访问令牌将限于所授予的scope。(全量Scope的定义在第三方应用与微信签署协议颁发开发者账号时就已经传递,支持后续第三方应用可以携带相关Scope字段定义直接访问微信认证服务器,确保是可以被识别的)

1、核心逻辑

       如下是RFC标准文档中的简化流程图,其中Access Token访问令牌是用来访问受保护的资源的凭据。一个访问令牌是一个字符串,它代表发给客户端的授权。令牌代表资源所有者授予的对特定范围和访问的时间(令牌是有范围和有效期的)。

A)用户(Resource Owner 资源所有者,一般指登录用户实体人)通过User Agent(用户代理,一般指手机或者电脑浏览器、或者是一个APP的前台界面,如知乎APP的前端页面,用户实体人是无法直接和软件交互的,根据不同的Oauth模式,可能不单独存在User Agent),打开客户端Client(客户端,也叫第三方应用,RFC标准定义里简单理解指的就是知乎APP的后台,这里就是点击了“通过微信登录的图标”)以后,客户端要求用户给予授权。---- 上图中做了简化,Client代表用户、用户代理、客户端三者在一起。
B)用户同意给予客户端授权(认证Code)。
C)客户端使用上一步获得的授权(认证Code),向认证服务器(Authorization Server,授权服务器,在对用户认证并且获得用户授权以后,给client发放access Token的服务器)申请令牌。
D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌(Access Token)。
E)客户端使用令牌,向资源服务器(Resource Server,资源服务器,即服务提供商存放用户受保护资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器)申请获取资源。
F)资源服务器确认令牌无误,同意向客户端开放资源。

以 最常使用的授权码模式 举例,:

(1)A和B相当于在网易云音乐支持微信登录的界面(网易云音乐的App界面上显示的“请选择微信登录”,你懂的!),让用户去输出微信的用户名和密码;

注意这里隐含了最关键的一点,就是输入微信用户名和密码后,微信认证服务器会先给Client(网易云音乐后台)颁发一个认证码Code;

(2)C和D相当于到Client(网易云音乐后台)带着认证码Code,到微信的认证服务器请求访问Token;

(3)Client带着颁发的Token去微信资源服务器获取想要的资源。

思考:为什么先要获取code再获取Access token?
1:张三访问A网,使用QQ授权登录,跳转到QQ授权页
2:完成QQ授权,跳转到 A网页面,并在参数中假如 token = 123456
3:A网获取token后,再去调用API完成相应操作。
注意,第二步的token,是在你的浏览器里实现的,跳转内容,也会在浏览器的地址输入框中体现。这就存在安全的风险,比如你恰好要分享内容拷贝了这个链接呢?又或者你的浏览器中毒了,被监听了这个链接呢? 总之是不安全的。如果返回的是一个CODE,获取token的环节是在A网站后台实现的,不会被泄露。你自己也看不到真正的token。这时候有人要问了,CODE如果泄露了怎么办,一般来说CODE只能兑换一次token,如果你获取CODE后,无法授权。则系统自然会发现被黑客攻击了。会重新授权,那么之前的token就无效了。

2、OAuth2.0四种授权方式

下面举例说明这四种方式授权步骤,假设有A和B两个网站,用户使用B网站的账号信息,登录A网站。参考站内写的较好的一篇文章:OAuth2详解:协议原理、授权流程与实战应用-CSDN博客

类型 描述 授权码模式 基于授权码code,是最严谨,最安全,流程最完整的授权模式 隐藏式 (简化模式) 授权码模式的简化版本,缺少了授权码环节 密码模式 第三方应用直接使用资源拥有者的用户密码去获取令牌 客户端凭证模式 第三方应用使用客户端凭证请求令牌

授权码方式

适用于有前端(APP或网页)的应用。第三方网站或APP先向授权服务器申请一个授权码(用户确认授权后,授权服务器将授权码返回给第三方网站),然后第三方网站或APP后台用授权码去申请访问令牌。下图引用至站内博客:

Oauth2的授权码模式中code和token的关系_oauth2 code获取token-CSDN博客 

上图是所有图中最好的例子,注意下图OAuthRFC官方文档描述容易误导观众,其中Resource owner相当于真实人,User Agent就是知乎App前台界面,Client就是知乎APP的后台,下图中没有话微信的资源服务器,只有认证服务器:

隐藏式

隐式授权是为了兼顾到在浏览器中用诸如JavaScript的脚本语言实现的客户端而优化的简化授权代码流程。有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。OAuth2 允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit);令牌直接存储到前端浏览器,是不太安全的。

在隐式授权流程中,不是发给客户端一个授权码,而是直接发给客户端一个访问令牌,而且不会对客户端进行认证。隐式授权提高了一些客户端(比如基于浏览器实现的客户端)的响应能力和效率,因为它减少了获得访问令牌所需的往返次数。

A)用户访问客户端(第三方应用),客户端引导(重定向)用户的代理(浏览器)去到授权服务器的授权页面,这个时候客户端会在URI上附上 clientId, redirectUri, requestScope以及 local state
B)授权服务器要求用户A输入用户密码认证身份,并询问用户A是否同意授权
C)假设用户同意授权,授权服务器使用 redirectUri (在authorization request中redirectUri或者客户端注册是的redirectUri)将用户导向客户端,并附上令牌 accessToken

D、E、G)是使用脚本能够将access token从(C)重定向的URI抽取出来,最后客户端就可以使用令牌向resourceServer请求资源了。

简单理解就是User agent本质上和Client是在一起的,不区分前后端!又增加了一个web-hosted client resource就是暂存获取到access token的,要通过脚本去解析就行!标准文档里写的太绕!

密码式

OAuth2 允许用户把用户名和密码直接告诉该应用,该应用就使用你的密码申请令牌,这种方式称为\"密码式\"(password);直接提供账号密码,风险很大,所以应当是用户高度新人客户端才会使用这种方式。

凭证式

客户端直接使用客户端凭证(client credentials)向认证服务器请求令牌,适用于没有前端的命令行应用。

二、OAuth关联核心名词概念

1. OIDC(OpenID Connect)

OIDC(OpenID Connect)是一种基于OAuth 2.0协议的身份认证开放标准,用于安全验证用户身份并跨系统传递用户信息。以下是其核心概念与原理的详细解析:OIDC在OAuth 2.0授权框架基础上增加了身份认证层,解决“用户是谁”的问题。与OAuth仅关注“授权”(允许第三方访问资源)不同,OIDC通过ID Token(身份令牌)向应用提供用户身份信息。

 关键角色如下:

End User(EU):终端用户

 Relying Party(RP):依赖方(客户端应用,如网站/App)

 OpenID Provider(OP):身份提供方(如Google、微信开放平台)

核心组件如下:

ID Token采用JWT(JSON Web Token)格式,包含用户身份信息(如用户ID、邮箱)及发行方(Issuer)签名经OP(Issuer)私钥签名,RP用公钥验证防篡改

 UserInfo EndpointRP通过Access Token访问此接口,获取用户详细资料(如头像、手机号)

能力 OAuth 2.0 OIDC 核心目标 资源访问授权 身份认证 + 授权 输出物 Access Token ID Token + Access Token 用户信息获取 需额外调用API 标准化UserInfo接口 安全级别 依赖实现 强制签名/加密验证 维度 OAuth 2.0 OpenID Connect (OIDC) 核心目标 授权(资源访问权限) 身份认证(用户身份验证)+ 授权 本质 授权框架 OAuth 2.0的身份认证扩展层 典型场景 应用A请求访问用户在应用B的相册 用户使用谷歌账号登录第三方应用

类比-记住这个例子,你就懂了
OAuth 2.0 = 酒店房卡(仅授权进入房间)
OIDC = 身份证 + 酒店房卡(同时验证身份并授权进入)

总结如下:

OpenID是Authentication,即认证,对用户的身份进行认证,判断其身份是否有效,也就是让网站知道“你是你所声称的那个用户”;

OAuth是Authorization,即授权,在已知用户身份合法的情况下,经用户授权来允许某些操作,也就是让网站知道“你能被允许做那些事情”。

由此可知,授权要在认证之后进行,只有确定用户身份只有才能授权。
 本质关系:OIDC = OAuth 2.0 + 身份认证规范(ID Token)

实现流程如下:
OAuth2提供了Access Token来解决授权第三方客户端访问受保护资源的问题;相似的,OIDC在这个基础上提供了ID Token来解决第三方客户端标识用户身份认证的问题。OIDC的核心在于在OAuth2的授权流程中,一并提供用户的身份认证信息(ID-Token)给到第三方客户端,ID-Token使用JWT格式来包装,得益于JWT(JSON Web Token)的自包含性,紧凑性以及防篡改机制,使得ID-Token可以安全的传递给第三方客户端程序并且容易被验证。应用服务器,在验证ID-Token正确只有,使用Access-Token向UserInfo的接口换取用户的更多的信息。

有上述可知,OIDC是遵循OAuth协议流程,在申请Access-Token的同时,也返回了ID-Token来验证用户身份。

EU:End User,用户。
RP:Relying Party ,用来代指OAuth2中的受信任的客户端,身份认证和授权信息的消费方;
OP:OpenID Provider,有能力提供EU身份认证的服务方(比如OAuth2中的授权服务),用来为RP提供EU的身份认证信息;
ID-Token:JWT格式的数据,包含EU身份认证的信息。
UserInfo Endpoint:用户信息接口(受OAuth2保护),当RP使用ID-Token访问时,返回授权用户的信息,此接口必须使用HTTPS。

2.  SSO(单点登录)

本节重点参考站内很好的文章:单点登录(SSO)详解——超详细-CSDN博客

单点登录(SSO,Single Sign On),主要是指在多个相关但独立的软件系统中,用户只需进行一次身份认证,就可以在这些系统之间无缝切换,而无需重复输入用户名和密码进行多次登录。是在企业内部多个应用系统(如考勤系统、财务系统、人事系统等)场景下,用户只需要登录一次,就可以访问多个应用系统。同理用户只需注销一次,就可以从多个应用系统退出登录。简单来说就是,一次登录,全部登录!一次注销,全部注销!!

单点登录的实现方案,一般就包含:Cookie、Session()、Token(JWT)

单点登录的本质就是在多个应用系统中共享登录状态。如果用户的登录状态是记录在 Session 中的,要实现共享登录状态,就要先共享 Session,比如可以将 Session 序列化到 Redis 中,让多个应用系统共享同一个 Redis,直接读取 Redis 来获取 Session。当然仅此是不够的,因为不同的应用系统有着不同的域名,尽管 Session 共享了,但是由于 Session ID 是往往保存在浏览器 Cookie 中的,因此存在作用域的限制,无法跨域名传递,也就是说当用户在 app1.com 中登录后,Session ID 仅在浏览器访问 app1.com 时才会自动在请求头中携带,而当浏览器访问 app2.com 时,Session ID 是不会被带过去的。实现单点登录的关键在于,如何让 Session ID(或 Token)在多个域中共享,有以下三种实现方式:

(1)基于 Cookie 的单点登录-父域Cookie

我们只需要将 Cookie 的 domain 属性设置为父域的域名(主域名),同时将 Cookie 的 path 属性设置为根路径,这样所有的子域应用就都可以访问到这个 Cookie 了。不过这要求应用系统的域名需建立在一个共同的主域名之下,如 tieba.baidu.com 和 map.baidu.com,它们都建立在 baidu.com 这个主域名之下,那么它们就可以通过这种方式来实现单点登录。

优点:

  • 实现相对简单,不需要复杂的服务器间通信。

  • 对于同域下的系统集成较为方便,不支持跨主域。

缺点:

  • 存在安全风险,因为 Cookie 可能被篡改或窃取。

  • 跨域情况下难以实现,因为浏览器的同源策略限制了不同域之间的 Cookie 访问。

(2)基于Token的单点登录-如:JSON Web Token(JWT)

(3)基于认证服务器的单点登录-独立服务器加密共享传递身份信息

(2)和(3)放到一起讲,是因为更多是共同一起使用的,尤其是跨域的互通登录,独立使用单一方法的场景很少:

Token-Based SSO是指使用Token来实现单点登录功能的一种方式。其原理是,用户首先在认证服务器上进行身份验证,如果验证成功,则认证服务器会颁发一个Token。然后,这个Token会被发送到客户端浏览器,并通过HTTP请求携带在请求头中或者以参数的形式传递给其他应用系统。当用户访问其他应用系统时,这些系统会向认证服务器验证Token,如果Token有效,则允许用户访问系统资源。

优点

安全性高:Token-Based SSO使用Token来实现用户身份认证,Token本身是无法被伪造的,并且可以通过加密和签名等手段进一步加强安全性,可以有效防止Cookie劫持和伪造攻击。
用户体验好:用户只需要进行一次身份验证,并获得一个Token即可访问所有被授权的系统资源,不需要多次输入用户名和密码。同时,用户可以在任何时间清除应用系统保存的Token,以保护自身安全。
易于处理跨域问题:Token-Based SSO不依赖Cookie,因此可以很容易地处理跨域问题。

缺点

实现复杂:Token-Based SSO需要在认证服务器上实现用户身份验证、令牌颁发和Token验证等逻辑。这些逻辑可能比较复杂,需要一定的技术能力。
维护成本高:认证服务器需要长期维护和管理,才能保证系统的正常运行。另外,如果有多个应用系统需要接入SSO,还需要在每个系统中添加相应的Token验证逻辑,增加了维护成本。

a. 最简单的实现:按照基础原理基于单一Token机制(通过登录任意子系统生成Token,并在整个系统中传递),或者单一认证服务器(不一定要有Token,通过加密传递身份验证的信息在不同子系统之间共享传递即可)

b. 当下就常用的典型实现案例就是上一节的OIDC实现SSO,基于认证服务器,同时颁发的身份信息基于JWT来传递,实现最复杂跨域的互通(比如登录一个APP软件,可以支持直接跳转到某一个官网网页,且免登录)登录,我们最常使用也是未来Agent跨域授权最多使用的就是JWT和代理服务器重定向配合,实现单点登录的原理说明如下:

1. 用户首次访问系统A时,需要进行登录。

2. 系统A带着用户登录信息重定向给认证系统。

3. 认证系统验证用户登录信息。

4. 验证通过后,返回一个token(Tip:token类似一种内部的通行证,包含了用户身份信息、登录状态和过期时间,在各个系统间共享。)

5. 认证系统带着token重定向给系统A,得知用户是已登录状态。

6. 系统A向用户返回请求的资源。

7. 用户访问系统B时,需要进行登录。

8. 系统B通过共享的token,得知用户是已登录状态。

9. 系统B向用户返回请求的资源。


总结

   未来面向Agent的授权机制,如果基于OAuth扩展(当前看绕不开),核心是加入Agent以后,用户和Agent-A调用的Agent-B/C/D...没有账号及其他必然关联,如何基于Agent任务中的关键字段进行扩展,携带关键的身份描述,是一个潜在的关键技术方向,后续会进一步展开讲解。