用户池、身份池与 JWT

开发者的 AWS 安全实践

Rahul Singh

Technical Product Manager

Cognito:一名两用的服务

Amazon Cognito

  • 为应用用户提供托管身份
  • 同一名称,两个独立服务

两道问题位于标注为 Amazon Cognito 的虚线边界上方。边界内并排两个蓝色面板:用户池(您的用户目录)与身份池(凭证代理)。两者的连线汇聚到下方橙色虚线框,说明许多应用同时使用二者。

开发者的 AWS 安全实践

Cognito:一名两用的服务

Amazon Cognito

  • 为应用用户提供托管身份
  • 同一名称,两个独立服务

您需要哪一个?

  • 登录与用户资料:用户池
  • 浏览器或移动端直连 AWS:身份池

两道问题位于标注为 Amazon Cognito 的虚线边界上方。边界内并排两个蓝色面板:用户池(您的用户目录)与身份池(凭证代理)。两者的连线汇聚到下方橙色虚线框,说明许多应用同时使用二者。

开发者的 AWS 安全实践

用户池负责登录

托管用户目录

  • 注册与登录
  • 重置密码
  • 多因素认证

纵向流程:应用用户登录到保存密码的用户池,用户池返回一个包含 ID token、access token 和 refresh token 的盒子

开发者的 AWS 安全实践

用户池负责登录

托管用户目录

  • 注册与登录
  • 重置密码
  • 多因素认证

 

成功后返回三个令牌

纵向流程:应用用户登录到保存密码的用户池,用户池返回一个包含 ID token、access token 和 refresh token 的盒子

开发者的 AWS 安全实践

用户池负责登录

托管用户目录

  • 注册与登录
  • 重置密码
  • 多因素认证

 

成功后返回三个令牌

  • ID token:是谁
  • Access token:能调用什么
  • Refresh token:后续换新令牌

纵向流程:应用用户登录到保存密码的用户池,用户池返回一个包含 ID token、access token 和 refresh token 的盒子

开发者的 AWS 安全实践

身份池签发 AWS 凭证

令牌不是凭证

  • 是应用的身份证明
  • 不是访问 AWS 服务的凭证

 

身份池:可信令牌进,AWS 凭证出

与用户池图相同结构的纵向流程:向身份池出示可信令牌,身份池验证签发者后返回限定角色且会过期的 AWS 凭证

开发者的 AWS 安全实践

身份池签发 AWS 凭证

令牌不是凭证

  • 是应用的身份证明
  • 不是访问 AWS 服务的凭证

 

身份池:可信令牌进,AWS 凭证出

  • 构建任务交换了一个 OIDC 令牌
  • 您持有的证明,换取一张门禁卡

与用户池图相同结构的纵向流程:向身份池出示可信令牌,身份池验证签发者后返回限定角色且会过期的 AWS 凭证

开发者的 AWS 安全实践

单个应用,双重组成

浏览器同时使用二者

  1. 登录并获取令牌
  2. 将该令牌发送到您的 API

不记名令牌:持有者即可使用

纵向流程。浏览器在用户池登录并获得令牌。该令牌分两路:左到您的 API,右到身份池。身份池返回凭证,凭证用于访问 S3。

开发者的 AWS 安全实践

单个应用,双重组成

浏览器同时使用二者

  1. 登录并获取令牌
  2. 将该令牌发送到您的 API
  3. 用同一令牌换取凭证

纵向流程。浏览器在用户池登录并获得令牌。该令牌分两路:左到您的 API,右到身份池。身份池返回凭证,凭证用于访问 S3。

开发者的 AWS 安全实践

单个应用,双重组成

浏览器同时使用二者

  1. 登录并获取令牌
  2. 将该令牌发送到您的 API
  3. 用同一令牌换取凭证
  4. 用凭证访问 S3

令牌给您的代码,凭证给 AWS

纵向流程。浏览器在用户池登录并获得令牌。该令牌分两路:左到您的 API,右到身份池。身份池返回凭证,凭证用于访问 S3。

开发者的 AWS 安全实践

令牌是带签名的文本

三个由点连接的段,标注为 Header、Payload 和 Signature。Payload 上有一个打开的锁,括号标示签名覆盖前两段。

JWT: JSON Web Token

  • Claims:关于用户的标注性声明
开发者的 AWS 安全实践

令牌是带签名的文本

三个由点连接的段,标注为 Header、Payload 和 Signature。Payload 上有一个打开的锁,括号标示签名覆盖前两段。

JWT: JSON Web Token

  • Claims:关于用户的标注性声明
  • 编码而非加密
  • 任何人都能读取,也能改动
开发者的 AWS 安全实践

读取前先验证

先验证,再读取

  • JWKS:JSON Web Key Set,签发方的公钥集
  • 用这些公钥校验签名

纵向闸门图。一个令牌到达后依次通过四项勾选检查:签名、签发方、受众与过期时间。签发方的公钥从侧面输入到签名校验。通过第四项后才进入绿色框读取声明。

开发者的 AWS 安全实践

读取前先验证

先验证,再读取

  • JWKS:JSON Web Key Set,签发方的公钥集
  • 用这些公钥校验签名

 

接着检查三项声明

  • iss:您的用户池
  • ID token 看 aud,access token 看 client_id
  • exp:尚未过期

纵向闸门图。一个令牌到达后依次通过四项勾选检查:签名、签发方、受众与过期时间。签发方的公钥从侧面输入到签名校验。通过第四项后才进入绿色框读取声明。

开发者的 AWS 安全实践

验证通过也可能不对

并排两张对比卡片。ID token 卡标注为身份令牌,展示 audience 声明中的 client ID,并注明不携带 scope;下方灰色框表示"是谁"。Access token 卡标注为访问令牌,展示其自身的 client 标识声明中的 client ID,并注明携带 scope;下方橙色框表示"可调用什么"。两卡片下方虚线条注明 Cognito 组声明同时出现在两类令牌中。

验证无误,也可能用错令牌

开发者的 AWS 安全实践

验证通过也可能不对

并排两张对比卡片。ID token 卡标注为身份令牌,展示 audience 声明中的 client ID,并注明不携带 scope;下方灰色框表示"是谁"。Access token 卡标注为访问令牌,展示其自身的 client 标识声明中的 client ID,并注明携带 scope;下方橙色框表示"可调用什么"。两卡片下方虚线条注明 Cognito 组声明同时出现在两类令牌中。

验证无误,也可能用错令牌

token_use 表示令牌类型

  • cognito:groups 同时出现在两类令牌中,并非 scope

  • scope:令牌可调用的范围

  • sub:是哪位用户,且恒定不变
  • 身份不等于权限
开发者的 AWS 安全实践

让我们一起练习吧!

开发者的 AWS 安全实践

Preparing Video For Download...