当前位置: 首页 > article >正文

API 安全之认证鉴权

作者:半天

前言

API 作为企业的重要数字资源,在给企业带来巨大便利的同时也带来了新的安全问题,一旦被攻击可能导致数据泄漏重大安全问题,从而给企业的业务发展带来极大的安全风险。正是在这样的背景下,OpenAPI 规范中针对 API 安全做了明确的定义和引导,以便用户可以安全的管理自己的 API。以下为 OpenAPI 的定义:What is openAPI【1】

An OpenAPI file allows you to describe your entire API, including:

  • Available endpoints (/users) and operations on each endpoint (GET /users, POST /users)
  • Operation parameters Input and output for each operation
  • Authentication methods
  • Contact information, license, terms of use, and other information.

可以看到认证鉴权是保护 API 必要而又最常用的手段。云原生 API 网关(以下简称-网关)是云原生网关的升级版,除继承了原云原生网关的全部能力,为用户叠加了 API 管理的能力。云原生 API 网关是完全遵循 OpenAPI 规范的阿里云新一代 API 网关,支持丰富的认证鉴权是其核心竞争力之一。

什么是认证鉴权

认证:是指验证用户身份的过程。简单来说,认证的目的是确认用户是谁。在这个过程中,用户通常需要提供某种凭证,例如用户名和密码、指纹、面部识别,或是其他生物特征,甚至是安全令牌(如两步验证中的验证码)。通过这些凭证,系统将用户的身份与已有的身份信息进行比对,从而确认其真实性。

鉴权:是指验证用户是否有权限访问某项资源或执行某项操作。虽然认证确认了用户身份,但它并不能确定该用户可以做什么。这方面的决策依赖于系统的权限管理策略。例如,在一个企业内部系统中,某位员工可能拥有访问某些文件的权限,但另一些敏感文件则可能只对高级管理层开放。鉴权的目的就是在用户经过认证后,根据其角色和权限设置,决定是否允许其访问特定资源或执行特定操作。

认证(Authentication)

Key 认证

云原生 API 网关中的 Key 认证叫 API Key 认证在消费者鉴权中统一透出。Key 认证是对用户密码认证方式的方式的优化版本,通过静态秘钥的方式,为用户提供了一种简便快捷且安全的认证方式,具有较为鲜明的优缺点:

优点:

1、简单易用,只需要在请求中传输秘钥即可,验证非常简单、性能高

2、认证过程无需用户参与,对自动化应用非常友好

3、服务器(网关)可以随时生成、汰换(删除)、重置(切换)秘钥,管理方便

缺点:

1、安全隐患,秘钥传输过程中很容易泄漏,泄漏后任何人都可以使用秘钥来伪装合法身份,进行未授权的操作;秘钥的分配和管理复杂

2、无法提供用户身份,审计较为困难

Api Key 认证的基本流程

云原生 API 网关的通过消费者授权来支持 API Key 认证,用户在消费者创建流程中,选择 API Key 身份认证,并且为其设置凭证来源和添加凭证。

云原生网关支持三种凭证来源设置方式:来源于固定 Header 头"Authorization"、来源于自定义 Header 头、以及来源自定义 QueryString。

curl  http://xxx.hello.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5
curl  http://xxx.hello.com/test -H 'x-api-key: 2bda943c-ba2b-11ec-ba07-00163e1250b5'

JWT 认证

什么是 JWT

JWT(JSON Web Token)是一种用于安全信息传递的开放标准,它允许在通信双方之间以 JSON 对象的形式传输安全信息,它设计为其中的信息可以被验证和信任。

JWT 通常由三部分组成:头部(Header)、载荷(Payload)和签名(Signature),其内容构造过程如下:

1. 头部(Header):

通常由两部分组成:令牌的类型(通常是 JWT)和所使用的签名算法(如 HMAC SHA256,在下文 JWKS 中指定);

{"alg": "HS256","typ": "JWT"
}

然后将头部进行 Base64 编码(该编码是可以对称解码的),得到第一部分:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

2. 载荷(Payload):

包含对 JWT 的声明(Claims),这些声明是关于实体(通常是用户)和其他数据的。定义细节如下:

iss:令牌颁发者。表示该令牌由谁创建,该声明是一个字符串
sub: Subject Identifier,iss提供的终端用户的标识,在iss范围内唯一,最长为255个ASCII个字符,区分大小写
aud:Audience(s),令牌的受众,分大小写的字符串数组
exp:Expiration time,令牌的过期时间戳。超过此时间的token会作废, 该声明是一个整数,是1970年1月1日以来的秒数
iat: 令牌的颁发时间,该声明是一个整数,是1970年1月1日以来的秒数
jti: 令牌的唯一标识,该声明的值在令牌颁发者创建的每一个令牌中都是唯一的,为了防止冲突,它通常是一个密码学随机值。这个值相当于向结构化令牌中加入了一个攻击者无法获得的随机熵组件,有利于防止令牌猜测攻击和重放攻击。

也可以新增用户系统需要使用的自定义字段,比如下面的例子添加了name 用户昵称:

{"sub": "1234567890","name": "John Doe"
}

然后将其进行 Base64 编码,得到 JWT 的第二部分:
JTdCJTBBJTIwJTIwJTIyc3ViJTIyJTNBJTIwJTIyMTIzNDU2Nzg5MCUyMiUyQyUwQSUyMCUyMCUyMm5hbWUlMjIlM0ElMjAlMjJKb2huJTIwRG9lJTIyJTBBJTdE

3. 签名(Signature):

为了生成签名部分,需要将编码后的头部、载荷和一个密钥(有些情况下是私钥)按照指定的算法(在下文 JWKS 中指定)组合在一起进行签名。

这个部分需要 Base64 编码后的 Header 和 Base64 编码后的 Payload 使用 . 连接组成的字符串,然后通过 Header 中声明的加密方式进行加密($secret 表示用户的私钥),然后就构成了 JWT 的第三部分。

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, '$secret');

将这三部分用 . 连接成一个完整的字符串,eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.JTdCJTBBJTIwJTIwJTIyc3ViJTIyJTNBJTIwJTIyMTIzNDU2Nzg5MCUyMiUyQyUwQSUyMCUyMCUyMm5hbWUlMjIlM0ElMjAlMjJKb2huJTIwRG9lJTIyJTBBJTdE.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

什么是 JWKS

在云原生 API 网关中,通过一组 JWKS 来描述 Header 信息,JWKS(JSON Web Key Set)是一种用于表示公钥和私钥集合的格式,通常用于支持 JWT 的身份验证和授权场景。

{"keys": [{"kty": "oct","k": "GFmQpiJq42SxAWyIN5vnlUzrVDhcdBjKZ8uw0ag3XO1","alg": "HS256"}]
}
{"keys": [{"e": "公钥的指数,例如AQAB","kid": "Key ID","kty": "使用的加密算法的家族,例如RSA,必填,大小写敏感","alg": "使用的具体的加密算法,例如RS256,必填,大小写敏感","use": "密钥的用途,例如sig,用于签名","n": "公钥的模值"}]
}

JWT 认证是云原生 API 网关消费者认证能力中的一种,其认证流程如下:

  1. 客户端向 API 网关发起认证请求,请求中一般会携带终端用户的用户名和密码。
  2. 网关将请求直接转发给后端服务。
  3. 后端服务读取请求中的验证信息(比如用户名、密码)进行验证,验证通过后使用私钥生成标准的 token,返回给网关。
  4. 网关将携带 token 的应答返回给客户端,客户端需要将这个 token 缓存到本地。
  5. 客户端向 API 网关发送业务请求,请求中携带 token。
  6. 网关使用用户通过 JWT 认证配置中 JWKS 设定的公钥对请求中的 token 进行验证,验证通过后,将请求透传给后端服务。
  7. 后端服务进行业务处理后应答。
  8. 网关将业务应答返回给客户端。

注意事项:

  1. JWT 通常设置有过期时间,过期时间的设置是一次性的,即客户端需要合理的管理 Token 的失效以免 Token 失效后影响访问,同时 Token 一旦颁发无法撤销,即使用户已经无权限,只要 Token 还在有效期,便依然可以访问,引发安全风险。
  2. JWT 默认是不加密,不要将秘密数据写入 JWT。
  3. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
  4. 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

AK/SK 认证

AK(Access Key ID)/SK(Access Secret Key): 是阿里云对一个明确的用户身份的一个抽象,云原生API网关沿用这个设计(注意:这里的云原生 API 网关生成的 AK/SK 与 RAM 的 AK /SK 相互独立,并不能互通使用),用来标识一个网关用户的身份,因为每个用户可能有多种身份类型,每种身份类型可以有多个凭证,类似多个账号,一组 AK/SK 可以简单对应到一组用户账密。

API 提供者给有权限的用户分配 AK/SK,API 消费者请求时带上 AK,服务端就可以识别调用者的信息,并进行更细粒度的权限管理。

HMAC: HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码,用于验证信息的完整性和身份验证。HMAC 结合了哈希函数和密钥的优点,提供了数据的完整性和安全认证的保证。

在基于 HMAC 的 AK/SK 认证过程中,HMAC 的主要作用是确保消息的完整性和身份验证。其具体作用如下:

  1. 身份验证: 通过使用共享密钥,只有持有该密钥的用户才能生成正确的 HMAC,从而可以确认消息的发送者的身份。
  2. 数据完整性: 任何对消息内容的修改都会导致 HMAC 值的变化,因此接收方可以通过计算接收到的消息的 HMAC 值来验证消息在传输过程中是否被篡改。
  3. 防止重放攻击: 在某些情况下,HMAC 还可以帮助防止重放攻击。通过在消息中加入时间戳或随机数,接收方可以确保消息的唯一性和新鲜性。

AK/SK(HMAC)认证是云原生 API 网关消费者认证能力中的一种,其认证流程包括客户端生成签名和服务端验证前面两个步骤。

客户端生成签名流程:

  1. 提取签名串:客户端从 HTTP 请求中提取出关键数据,组成一个签名串,如云原生 API 网关的签名串内容主要由以下 7 部分组成:
HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters
POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789

提取原签名串并追加 AK/SK 认证的 AK 和签名算法,形成最终签名串,header 之间用 \n 换行符分隔

POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
/http2test/test?param1=test&password=123456789&username=xiaoming
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-timestamp:1525872629832##添加AK/SK认证Headers
x-ca-key:203753385,AK/SK身份配置中的AK
x-ca-signature-method:HmacSHA256
  1. 加密签名:对第1步提取的签名串使用 HmacSha256 算法进行加密和 Base64 编码处理得到签名内容,如:
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);
  1. 添加签名:将第 2 步生成的签名和参与前面参与加签的 header 作为 header 一并添加到 http 请求中:
x-ca-signature-headers:参与签名的header的key的集合,英文逗号分隔
x-ca-signature:签名,必选。

得到待发送给网关的携带签名的 HTTP 请求:

POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##添加AK/SK认证Headers
x-ca-key:203753385
x-ca-signature-method:HmacSHA256##添加AK/SK认证Headers签名相关的headers
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=

网关验证签名流程图:

  1. 提取签名串:从接收到的请求中提取关键数据,得到一个用来签名的字符串。

收到的 HTTP 请求:

POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##AK/SK(HMAC)认证新增的header
x-ca-key:203753385
x-ca-signature-method:HmacSHA256##签名新增的header
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
  1. 提取 AK:从接收到的请求中读取 AK ,通过 AK 查询到对应的 SK。

  2. 提取签名串并计算签名:使用加密算法和 SK 对关键数据签名串进行加密处理,得到签名。

POST /http2test/test?param1=test HTTP/1.1
host:api.aliyun.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789##AK/SK(HMAC)认证新增的header
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
  1. 签名验证:从接收到的请求中读取客户端签名,服务端使用第 3 不获取的私钥进行签名验证,对比服务器端签名和客户端签名的一致性,从而判断客户是否认证通过。

OAuth2 认证

什么是 OAuth 2.0

OAuth 2.0 是一种用于授权的协议,广泛用于互联网应用以实现安全的授权机制。OAuth 2.0 定义以下几种角色:

  • 资源拥有者(Resource Owner): 通常是用户,拥有数据访问权限,以下简称为用户
  • 客户端(Client): 请求访问资源的应用程序。
  • 授权服务器(Authorization Server): 负责验证用户并发放访问令牌的服务器。
  • 资源服务器(Resource Server): 存储用户数据的服务器。

OAuth 2.0 协议的流程主要包含以下几个步骤:

1、客户端请求用户授权,此时通常会跳转第三方登录页
2、资源拥有者用户同意授权
3、客户端使用已获得授权,请求授权服务器发放Access Token
4、授权服务器返回Access Token
5、客户端使用Access Token,请求资源服务器
6、资源服务器验证Access Token,并返回受保护的资源
抽象流程图

OAuth 2.0 协议定义了 4 种授权模式:
  • 授权码模式(authorization code)
  • 简化模式(implicit)
  • 密码模式(resource owner password credentials)
  • 客户端模式(client credentials)

**授权码模式:

其中授权码模式是最为广泛使用的授权模式,它适用于用户授予第三方客户端访问自身资源的场景,其核心流程如下:

用户通过User-Agent(用户代理,通常是浏览器)与Client第三方客户端进行交互,其交互流程主要包含以下三步:
A、浏览器访问客户端应用程序
B、用户通过浏览器与客户端交互
C、客户端通过浏览器透传AuthorizationCode及RedirectUri等参数User-Agent代理用户与授权服务器交互,其交互流程如下:
A、User-Agent使用第三方授权,User-Agent携带client定位符与重定向uri地址将用户指向
认证服务器的认证页
B、用户通过User-Agent授权访问
C、授权服务器进行认证鉴权,认证鉴权通过后将授权码附在A步骤重定向Uri地址之后,然后导向重定向Uri
D、客户端收到授权码将其附在重定向uri中,请求授权服务器,获取Access Token
E、授权服务器和核对重定向uri地址和授权码无误后,发放Access Token和Refresh Token(可选的)

授权码授权流程图:

客户端模式:

客户端模式是一种简化的授权模式,它是客户端以"Client"的名义请求资源服务器,而不是以"用户"名义,它适用于受信的客户端访问。

OIDC 认证

OIDC 是 OpenID Connect 的简称。OIDC(OpenID Connect)是在 OAuth 2.0 之上构建的身份认证层,为应用程序提供用户身份验证的能力。

为什么要有OIDC
  1. 身份验证和授权的分离: OAuth 2.0 主要关注授权 Authorization,而 OIDC 扩展了认证的抽象,任意完成身份认证的 Provider 实现,都能成为 Identity Provider,并作为 OpenID Provider 在 OIDC 协议中承担认证的职责
  2. 用户信息获取: OIDC 在扩展认证的基础提供了标准化的 API 来获取用户的基本信息,使得开发者能够轻松集成用户的个人信息。

总结一下:OAuth 2.0 设计之初是为了解决授权的问题,而 OIDC  在 OAuth 2.0 的基础上扩展了关于认证的定义并且添加一组获取用户信息的 API,且 OIDC 完全兼容 OAuth 2.0 协议。

OIDC 基于 OAuth 2.0 协议实现的角色及关键资源定义

OIDC 认证

通过云原生 API 网关的 OIDC 认证功能,可以实现在网关统一认证鉴权,并支持域名级别的黑白名单方便用户灵活的管理认证授权的粒度,其核心流程如下:

OIDC 认证详细流程

  1. 访问用户受保护的资源(需要认证授权访问的 API)
curl --url "foo.bar.com/headers"
  1. 云原生 API 网关将请求重定向到身份提供商(IDP)登录页同时携带 client_id、response_type、scope 等 OIDC 认证的参数,response_type 设置为 code,即使用 OAuth 2.0 授权码模式获取 token,同时设置 csrf cookie, 防御 csrf 攻击(Cross-Site Request Forgery -跨站请求伪造)
curl --url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/authorize"\--url-query "approval_prompt=force" \--url-query "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--url-query "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \--url-query "response_type=code" \--url-query "scope=openid+email+offline_access" \--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \--header "Set-Cookie: _oauth2_proxy_csrf=LPruATEDgcdmelr8zScD_ObhsbP4zSzvcgmPlcNDcJpFJ0OvhxP2hFotsU-kZnYxd5KsIjzeIXGTOjf8TKcbTHbDIt-aQoZORXI_0id3qeY0Jt78223DPeJ1xBqa8VO0UiEOUFOR53FGxirJOdKFxaAvxDFb1Ok=|1718962455|V1QGWyjQ4hMNOQ4Jtf17HeQJdVqHdt5d65uraFduMIU=; Path=/; Expires=Fri, 21 Jun 2024 08:06:20 GMT; HttpOnly"
  1. 重定向到身份提供商(IDP)登录页(在云原生网关为用户配置的认证服务提供的登录页)

  1. 用户输入用户名密码登录完成,完成认证授权

  2. 携带授权码重定向到云原生 API 网关并携带了 state 参数用于验证 csrf cookie ,授权码用于交换 token

curl --url "http://foo.bar.com/oauth2/callback" \--url-query "state=nT06xdCqn4IqemzBRV5hmO73U_hCjskrH_VupPqdcdw%3A%2Ffoo" \--url-query "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm"
  1. 校验 csrf cookie 中加密存储的 state 值与 url 参数中的 state 值必须相同

  2. 利用授权码,请求身份提供商(IDP)交换 id_token 和 access_token、refresh_token

curl -X POST \--url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/oauth/token" \--data "grant_type=authorization_code" \--data "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--data "client_secret=ekqv5XoZuMFtYms1NszEqRx03qct6BPvGeJUeptNG4y09PrY16BKT9IWezTrrhJJ" \--data "redirect_uri=http%3A%2F%2Ffoo.bar.com%2Foauth2%2Fcallback" \--data "code=0bdopoS2c2lx95u7iO0OH9kY1TvaEdJHo4lB6CT2_qVFm" \

返回的请求里包含了 id_token, access_token,refresh_token 用于后续刷新 token

{"access_token": "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ","refresh_token": "GrZ1f2JvzjAZQzSXmyr1ScWbv8aMFBvzAXHBUSiILcDEG","id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imc1Z1ExSF9ZbTY0WUlvVkQwSVpXTCJ9.eyJlbWFpbCI6IjE2MDExNTYyNjhAcXEuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJpc3MiOiJodHRwczovL2Rldi1vNDN4YjFtejd5YTdhY2g0LnVzLmF1dGgwLmNvbS8iLCJhdWQiOiJZYWdGcVJEOXRmTklhYWM1QmFtamhzU2F0anJBbnNuWiIsImlhdCI6MTcxOTE5ODYzOCwiZXhwIjoxNzE5MjM0NjM4LCJzdWIiOiJhdXRoMHw2NjVkNzFlNzRjMTMxMTc3YmU2NmU2MDciLCJzaWQiOiJjdDJVOF9ZUS16VDdFOGkwRTNNeUstejc5ZGlWUWhhVSJ9.gfzXKJ0FeqzYqOUDLQHWcUG19IOLqkpLN09xTmIat0umrlGV5VNSumgWH3XJmmwnhdb8AThH3Jf-7kbRJzu4rM-BbGbFTRBTzNHeUajFOFrIgld5VENQ_M_sXHkTp0psWKSr9vF24kmilCfSbvC5lBKjt878ljZ7-xteWuaUYOMUdcJb4DSv0-zjX01sonJxYamTlhji3M4TAW7VwhwqyZt8dBhVSNaRw1wUKj-M1JrBDLyx65sroZtSqVA0udIrqMHEbWYb2de7JjzlqG003HRMzwOm7OXgEd5ZVFqgmBLosgixOU5DJ4A26nlqK92Sp6VqDMRvA-3ym8W_m-wJ_A","scope": "openid email offline_access","expires_in": 86400,"token_type": "Bearer"
}
  1. 网关将获得的 id_token, access_token, refresh_token 加密存储在 cookie _oauth2_proxy 中

9.重定向到用户访问的后端服务并设置 cookie,用于后续用户登录状态的验证,同时清除 csrf 防护中设置的 cookie _oauth2_proxy_csrf

"Set-Cookie": ["_oauth2_proxy_csrf=; Path=/; Expires=Mon, 24 Jun 2024 02:17:39 GMT; HttpOnly","_oauth2_proxy=8zM_Pcfpp_gesKFe4SMg08o5Iv0A8WAOQOmG1-vZBbQ56UggYVC0Cu-gFMEoxJZU5q1O5vqRlVBizlLetgVjRCksGVbttwl8tQ7h5YiyIubbbtvF1T4JzLh3QfzUUrwbB-VznOkh8qLbjAhddocecjBt4rMiDyceKXqMr4eO5TUEMx4vHtJYnTYalMeTYhGXk5MNSyrdZX9NnQnkdrCjiOQM13ggwob2nYwhGWaAlgzFSWkgkdtBy2Cl_YMWZ8_gKk9rDX289-JrJyGpr5k9O9RzRhZoY2iE3Mcr8-Q37RTji1Ga22QO-XkAcSaGqY1Qo7jLdmgZTYKC5JvtdLc4rj3vcbveYxU7R3Pt2vEribQjKTh4Sqb0aA03p4cxXyZN4SUfBW1NAOm4JLPUhKJy8frqC9_E0nVqPvpvnacaoQs8WkX2zp75xHoMa3SD6KZhQ5JUiPEiNkOaUsyafLvht6lLkNDhgzW3BP2czoe0DCDBLnsot0jH-qQpMZYkaGr-ZnRKI1OPl1vHls3mao5juOAW1VB2A9aughgc8SJ55IFZpMfFMdHdTDdMqPODkItX2PK44GX-pHeLxkOqrzp3GHtMInpL5QIQlTuux3erm3CG-ntlUE7JBtN2T9LEb8XfIFu58X9_vzMun4JQlje2Thi9_taI_z1DSaTtvNNb54wJfSPwYCCl4OsH-BacVmPQhH6TTZ6gP2Qsm5TR2o1U2D9fuVkSM-OPCG9l3tILambIQwC3vofMW6X8SIFSmhJUDvN7NbwxowBiZ6Y7GJRZlAk_GKDkpsdrdIvC67QqczZFphRVnm6qi-gPO41APCbcO6fgTwyOhbP3RrZZKWSIqWJYhNE3_Sfkf0565H7sC7Hc8XUUjJvP3WnjKS9x7KwzWa-dsUjV3-Q-VNl-rXTguVNAIirYK-qrMNMZGCRcJqcLnUF0V_J2lVmFyVsSlE3t0sDw2xmbkOwDptXFOjQL5Rb4esUMYdCBWFajBfvUtcZEFtYhD0kb6VcbjXO3NCVW5qKh_l9C9SRCc7TG1vcRAqUQlRXHacTGWfcWsuQkCJ3Mp_oWaDxs1GRDykQYxAn5sTICovThWEU2C6o75grWaNrkj5NU-0eHh3ryvxLmGLBOXZV9OQhtKShWmUgywSWMxOHOuZAqdAPULc8KheuGFjXYp-RnCbFYWePJmwzfQw89kSkj1KUZgMYwKEjSz62z2qc9KLczomv76ortQzvo4Hv9kaW6xVuQj5R5Oq6_WMBOqsmUMzcXpxCIOGjcdcZRBc0Fm09Uy9oV1PRqvAE4PGtfyrCaoqILBix8UIww63B07YGwzQ-hAXDysBK-Vca2x7GmGdXsNXXcTgu00bdsjtHZPDBBWGfL3g_rMAXr2vWyvK4CwNjcaPAmrlF3geHPwbIePT0hskBboX1v1bsuhzsai7rGM4r53pnb1ZEoTQDa1B-HyokFgo14XiwME0zE1ifpNzefjpkz1YY2krJlqfCydNwoKaTit4tD2yHlnxAeFF9iIrxzSKErNUFpmyLa7ge7V33vhEH-6k5oBTLE2Q2BrC6aAkLCcPwU9xv_SzBDQPRY0MEYv3kGF03Swo1crRbGh-aifYX9NiHDsmG6r1vAnx0MAOw2Jzuz2x6SSdfBrzlcoWBlrwiZzd9kAKq75n1Uy9uzZ8SRnkBrEZySHBwEbu196VklkRE0jqwC-e3wWNNuviSOfwkVeX-7QdOoO10yw9VK2sW52lFvIEf4chv_ta7bGfAZOWBjpktG6ZLD81SE6A88zpqG2SysSyNMp9hl-umG-5sFsjCn_c9E8bDvwkUOUVb9bNqhBDsZgR0BNPawiOZjmyfhzmwmWf-zgFzfFSV6BvOwNRi3sCOHTsWcuk9NBQ_YK8CpNkVl3WeIBSDfidimuC_QV9UWKs1GPk35ZRkM4zKtLY2JsBFWKaDy_P80TcOzcMBoP8gIBClXZ-WUqfE8s1yyc4jrq-qL1_wJ24ef1O9FktsbyZiDKXw2vnqsT8-g_hCeG-unrT1ZFscf8oNdqczARHX-K4vKH2k3uIqEx1M=|1719199056|2rsgdUIClHNEpxBLlHOVRYup6e4oKensQfljtmn4B80=; Path=/; Expires=Mon, 01 Jul 2024 03:17:36 GMT; HttpOnly"
]
  1. 校验是否存在此 cookie,并且 cookie 中存储了用户的 token 信息同时查看是否过期

11.使用含有 Authorization 头部存储用户的 access_token 访问相应的 API

curl --url "foo.bar.com/headers"--header "Authorization: Bearer eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYtbzQzeGIxbXo3eWE3YWNoNC51cy5hdXRoMC5jb20vIn0..WP_WRVM-y3fM1sN4.fAQqtKoKZNG9Wj0OhtrMgtsjTJ2J72M2klDRd9SvUKGbiYsZNPmIl_qJUf81D3VIjD59o9xrOOJIzXTgsfFVA2x15g-jBlNh68N7dyhXu9237Tbplweu1jA25IZDSnjitQ3pbf7xJVIfPnWcrzl6uT8G1EP-omFcl6AQprV2FoKFMCGFCgeafuttppKe1a8mpJDj7AFLPs-344tT9mvCWmI4DuoLFh0PiqMMJBByoijRSxcSdXLPxZng84j8JVF7H6mFa-dj-icP-KLy6yvzEaRKz_uwBzQCzgYK434LIpqw_PRuN3ClEsenwRgIsNdVjvKcoAysfoZhmRy9BQaE0I7qTohSBFNX6A.mgGGeeWgugfXcUcsX4T5dQ"
  1. 后端服务根据 access_token 获取用户授权信息并返回对应的 HTTP 响应
{"email": "******","email_verified": false,"iss": "https://dev-o43xb1mz7ya7ach4.us.auth0.com/","aud": "YagFqRD9tfNIaac5BamjhsSatjrAnsnZ","iat": 1719198638,"exp": 1719234638,"sub": "auth0|665d71e74c131177be66e607","sid": "ct2U8_YQ-zT7E8i0E3MyK-z79diVQhaU"
}

用户令牌刷新

  1. 访问用户受保护的资源(需要认证授权访问的 API)
curl --url "foo.bar.com/headers"
  1. 检查 AccessToken 令牌的过期时间,如果过期或者即将过期,请求刷新令牌

  2. 如果在 cookie 中检测到存在 refresh_token,则可以访问相应的接口以交换新的 id_token,access_token

curl -X POST \--url "https://dev-o43xb1mz7ya7ach4.us.auth0.com/oauth/token" \--data "grant_type=refresh_token" \--data "client_id=YagFqRD9tfNIaac5BamjhsSatjrAnsnZ" \--data "client_secret=ekqv5XoZuMFtYms1NszEqRx03qct6BPvGeJUeptNG4y09PrY16BKT9IWezTrrhJJ" \--data "refresh_token=GrZ1f2JvzjAZQzSXmyr1ScWbv8aMFBvzAXHBUSiILcDEG"
  1. 更新会话,并存储新的令牌

  2. 携带 Authorization 标头并使用新的 access_token 访问对应 API

  3. 后端服务根据 access_token 获取用户授权信息并返回对应的 HTTP 响应

云原生网关中的认证鉴权能力

云原生 API 网关支持以下三类认证鉴权的方式,用户可以按照自己的业务场景选择适合的认证类型和方式。

云原生 API 网关的其他安全能力

保护 API 安全,是云原生 API 网关作为接入层重要的能力,认证鉴权只是云原生 API 网关诸多安全能力中的一部分;云原生网关还提供下表中的多种安全能力,以便用户进一步维护企业API资产的安全。

相关链接:

【1】What is openAPI:

https://swagger.io/docs/specification/v3_0/about/

相关文章:

API 安全之认证鉴权

作者:半天 前言 API 作为企业的重要数字资源,在给企业带来巨大便利的同时也带来了新的安全问题,一旦被攻击可能导致数据泄漏重大安全问题,从而给企业的业务发展带来极大的安全风险。正是在这样的背景下,OpenAPI 规范…...

Gateway实战入门(四)、断言-请求头以及请求权重分流等

spring cloud-Gateway:断言-请求头以及请求权重分流等 一、断言Header信息要求项目前置环境要求案例一、断言-请求头信息-匹配X-Request-Id1、配置文件及代码2、测试案例二、断言-请求头信息-匹配API版本场景主要配置信息案例三、断言-请求头信息:匹配请求来源场景主要配置信…...

【人工智能】从 Llama 到 DeepSeek:开源大模型的演进与技术对比

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着人工智能的迅猛发展,开源大语言模型(LLM)在自然语言处理领域扮演着越来越重要的角色。本文从 Meta 的 Llama 系列开始,追溯开源大模…...

[测试] Google Test | 主流的 C 测试框架

目录 GoogleTest 2. 准备工作 3. 测试 4.怎么用 Attention is All You Need 写项目代码的时候 边写边测试 非常重要,这样可以帮助我们减少很多的问题。 这篇文章后面 主要以 GoogleTest 为例,进行介绍最近找了些 gtest 相关的资料,学习了下.后面主要…...

OpenCV 图形API(3)高层次设计概览

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 描述 G-API 是一个异构框架,提供了统一的 API 来使用多个支持的后端编程图像处理流水线。 关键的设计理念是在指定使用哪些内核和设备时保持流…...

51单片机的五类指令(五)——位操作类指令

目录 一、位传送指令 1、MOV C, bit 2、MOV bit, C 3、位传送指令的应用场景 二、位变量修改指令 1、CLR(清 0 指令) 2、SETB(置 1 指令) 3、位变量修改指令的应用场景 三、位变量逻辑操作指令 1、位变量逻辑与指令 ANL…...

用python编写poc的流程

目录 一、POC 编写核心流程 二、常用 Python 库与工具 三、POC 框架推荐 四、高级优化技巧 五、安全规范与注意事项 六、实战案例:命令注入漏洞验证 一、POC 编写核心流程 漏洞分析 确定漏洞类型:根据目标特征判断漏洞类型(如 SQL 注入、…...

碰一碰发视频网页版本开发的源码搭建指南

引言 在数字化信息快速传播的时代,近场通信(NFC)技术为信息交互带来了新的便捷方式。通过网页版本实现碰一碰发视频功能,能够让用户在浏览器环境中轻松实现视频分享,拓展了视频传播的途径。本文将详细介绍碰一碰发视频…...

【含文档+PPT+源码】基于Python爬虫二手房价格预测与可视化系统的设计与实现

项目介绍 本课程演示的是一款基于Python爬虫二手房价格预测与可视化系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 带你从零开始部署运行本套系统 该项…...

多台服务器上docker部署 Redis 集群

规划集群节点 确保你的服务器有固定 IP,比如: 172.16.17.100 172.16.17.101 172.16.17.102 每台服务器运行 2 个 Redis 节点,总共 6 个节点,满足 Redis Cluster 最小节点数要求。 2. 在每台服务器上运行 Redis 在每台服务器上执行…...

Redis-16.在Java中操作Redis-Spring Data Redis使用方式-操作有序集合类型的数据

一. 操作有序集合类型的数据 package com.sky.test;import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.*;imp…...

针对单台浪潮服务器运行Windows Server 2019和SQL Server的MES系统场景、高效能监控策略(兼顾软硬件健康)

--- ### **一、监控架构设计原则** - **轻量化**:优先使用Windows原生工具和免费方案,避免额外资源消耗 - **关键性聚焦**:仅监控直接影响MES运行的核心指标 - **自动化告警**:异常发生时主动触发通知,无需人工巡检 -…...

Vue Transition组件类名+TailwindCSS

#本文教学结合TailwindCSS实现一个Transition动画的例子# 举例代码&#xff1a; <transition enter-active-class"transition-all duration-300 ease-out"enter-from-class"opacity-0 translate-y-[-10px]"enter-to-class"opacity-100 translate-…...

Anaconda和Pycharm的区别,以及如何选择两者

目录 主要区别详细说明如何选择&#xff1f;Anaconda的使用步骤 主要区别 Anaconda 和 PyCharm 是 Python 开发中常用的两个工具&#xff0c;但它们的定位和功能完全不同。以下是它们的主要区别&#xff1a; 对比项AnacondaPyCharm类型Python 发行版 包管理工具Python 集成开…...

STM32智能手表——任务线程部分

RTOS和LVGL我没学过&#xff0c;但是应该能硬啃这个项目例程 ├─Application/User/Tasks # 用于存放任务线程的函数 │ ├─user_TaskInit.c # 初始化任务 │ ├─user_HardwareInitTask.c # 硬件初始化任务 │ ├─user_RunModeTasks.c…...

SQL命令

一、表的创建 SQL MS Access、MySQL 和 SQL Server 数据类型 | 菜鸟教程 SQL Server 和 MySQL 中的 Date 函数 | 菜鸟教程 1.1、创建表 CREATE TABLE Citys (CityID int PRIMARY KEY,CityName varchar(255) );CREATE TABLE Per (PersonID int PRIMARY KEY, …...

DRM_CLIENT_CAP_UNIVERSAL_PLANES和DRM_CLIENT_CAP_ATOMIC

drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1); 这两行代码用于启用 Linux DRM&#xff08;Direct Rendering Manager&#xff09;客户端的两个关键特性&#xff0c;具体作用如下&#xff1a; 1. drmSetClientCap…...

anaconda安装 创建虚拟环境+pycharm中conda环境配置

miniconda下载安装参考以下链接&#xff1a; https://blog.csdn.net/2301_76831056/article/details/143165738?fromshareblogdetail&sharetypeblogdetail&sharerId143165738&sharereferPC&sharesourceweixin_63339973&sharefromfrom_link &#xff08;注…...

EasyExcel导出导入excel工具类

接上一篇EasyExcel导出导入excel的文章&#xff0c;附上一份完整的工具类代码。对于字体颜色名称&#xff0c;请参考这篇文章。 POI字体颜色 小技巧 类转换用属性拷贝不同类如果有相同属性&#xff0c;则使用反射验证&#xff0c;减少代码量 private List<Person> vali…...

终端SSH连接工具SecureCRT安装和连接Linux

SecureCRT 9.5是一款集终端仿真与加密功能于一身的专业软件&#xff0c;其坚如磐石的安全性、高效的信息传输能力以及高度可定制的会话管理&#xff0c;使得它成为众多用户的首选。该软件不仅支持SSH2、SSH1、Telnet等多种协议&#xff0c;还提供了Relogin、Serial、TAPI、RAW等…...

赛逸展2025“创新引擎”启动:限量席位,点亮科技绿色新征程

当今时代&#xff0c;科技革新与绿色发展已然成为推动社会进步的双引擎。2025第七届亚洲消费电子技术贸易展&#xff08;赛逸展&#xff09;敏锐捕捉这一趋势&#xff0c;重磅打造“科技创新专区”&#xff0c;并面向科技、绿色企业吹响限量招募号角。 这个独具特色的专区紧扣…...

Spring的 init-method, @PostConstruct, InitializingBean 对比

Spring的 init-method, PostConstruct, InitializingBean 对比 在Spring框架中&#xff0c;init-method、PostConstruct和InitializingBean都是用于定义Bean初始化后执行逻辑的机制&#xff0c;但它们在实现方式、耦合度、执行顺序及适用场景上有所不同。以下是它们的对比总结…...

Gogs 精简备份与恢复方案(仅SQLite数据库和配置)

一、备份方案设计 1. 备份内容 SQLite数据库文件&#xff1a;/home/git/gogs/data/gogs.db 配置和附件&#xff1a;/home/git/gogs/custom 整个目录 2. 备份策略 每周日凌晨2点执行完整备份 保留最近4周的备份文件 备份存储在独立分区 /backup&#xff08;使用永久化挂载…...

FPGA实现数码管显示分秒时间

目录 一. verilog实现 二. 烧录验证 三. 结果验证 使用开发板&#xff1a;DE2-115开发板 一. verilog实现 要实现分和秒&#xff0c;需要知道定时器的频率&#xff0c;通过查手册可知&#xff0c;我使用的开发板时钟为50hz&#xff0c;也就是时钟一个周期是2微秒。 5000000…...

读书记录九之《在峡江的转弯处-陈行甲人生笔记》

距离上本读完的书&#xff0c;写读后感有很长一段时间了&#xff0c;中间读了几本书&#xff0c;但都没写点文字&#xff0c;没错&#xff0c;是懒病又犯了。陈行甲这本书&#xff0c;一开始从网络上推荐看到&#xff0c;看之前介绍是一本人物自传的回忆录。我个人对这类贴近的…...

可视化开发:用Qt实现Excel级动态柱状图

Qt柱状图 QtChart 首先我们介绍一下 图表建立的基础&#xff1a;Qt Charts QtChart 是Qt框架的一个模块&#xff0c;专注与提供交互式数据可视化功能 俗话就是 用于用户轻松创建各种类型的图表和图形界面 它包含的图表类型有很多&#xff1a;折线图&#xff0c;饼图&#x…...

从零实现Json-Rpc框架】- 项目实现 - 基于Dispatcher模块的RPC框架

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

kubekey -实现懒人一键部署K8S集群

kubekey -实现懒人一键部署K8S集群 操作步骤 官网&#xff1a; https://kubesphere.io/zh/ 一、执行以下命令快速创建一个 Kubernetes 集群。 Master节点 如果您访问 GitHub/Googleapis 受限&#xff0c;请登录 Linux 主机&#xff0c;执行以下命令设置下载区域。 [roottest ~]…...

Android设计模式之模板方法模式

一、定义&#xff1a; 定义一个操作中的算法的框架&#xff0c;而将一些步骤延迟到子类中&#xff0c;使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 二、结构&#xff1a; AbstractClass抽象类&#xff1a;定义算法的骨架&#xff0c;包含模板方法和若干…...

李宏毅机器学习笔记(1)—机器学习基本概念+深度学习基本概念

机器学习基本概念 1、获取模型 步骤 1.1、假定未知函数 带未知参数的函数 1.2、定义损失函数 真实值&#xff1a;label MAE MSE 几率分布&#xff0c;cross-entropy? 1.3、优化 单独考虑一个参数 让损失函数最小&#xff0c;找导数为零的点 单独考虑w&#xff0c;w…...