告别固定密钥!在单一账户下用 Cognito 实现 AWS CLI 的 MFA 单点登录

大家好,很多朋友,特别是通过合作伙伴或服务商使用 AWS 的同学,可能会发现自己的 IAM Identity Center 功能受限,无法像在组织管理账户里那样轻松配置 CLI 的 SSO (aws configure sso)。那么,我们就要放弃治疗,退回使用古老的、不安全的静态 IAM 用户密钥吗?

绝对不行!今天,我就教大家如何利用 AWS Cognito,在自己的单一账户内,从零开始打造一个支持 MFA 的 CLI 登录门户,彻底告别固定凭据的烦恼。
在这里插入图片描述

为什么是 Cognito?

在前面提到的场景下,我们需要的本质是一个“身份验证服务”,它能:

  1. 验证我就是我(最好带上 MFA)。
  2. 验证通过后,给我一个“临时通行证”(临时的 AWS STS 凭证)。
  3. 这个过程要能被 CLI 工具自动化。

Cognito 完美地满足了这三点。它就像一个为我们自己搭建的、轻量级的“迷你 IAM Identity Center”。

而另一个选项 AWS Managed Microsoft AD,虽然技术上也能通过 SAML 联合登录实现,但它是一个重量级且昂贵的解决方案,通常用于已经深度绑定微软生态的大型企业。对于个人或小团队在单一账户下的需求来说,完全是“杀鸡用牛刀”,成本和复杂度都太高了。

所以,我们的主角就是 Cognito

方案核心:Cognito 用户池 + 身份池 = 临时凭证生成器

这个方案的核心是 Cognito 的两大组件协同工作:

  1. Cognito 用户池 (User Pool): 我们的“用户数据库”。我们在这里创建用户,并为用户强制启用 MFA。它只负责认证(Authentication)——确认我们是谁。
  2. Cognito 身份池 (Identity Pool): 我们的“权限交换中心”。它信任来自用户池的已认证用户,并被授权可以为他们代领一个拥有特定权限的 IAM 角色(临时凭证)。它负责授权(Authorization)——决定我们能做什么。

整个流程就像这样:
CLI -> Cognito 用户池 (输入密码+MFA码) -> 获取身份令牌 -> Cognito 身份池 (用身份令牌交换) -> 获取临时 AWS 凭证 (Access Key, Secret Key, Session Token)

实战步骤:四步打造 CLI 登录系统
第 1 步:创建 Cognito 用户池 (用户中心)
  1. 进入 AWS Cognito 服务控制台,点击“创建用户池”。
  2. 在配置登录体验时,选择“Cognito user pool”作为提供商类型。
  3. 关键: 在“多重要素认证 (MFA)”部分,选择 “强制 (Required)”,并选择“验证器应用 (Authenticator apps)”作为 MFA 类型。这样就确保了所有登录行为都必须经过 MFA。
  4. 其他设置可以保持默认,完成用户池的创建。
  5. 在创建好的用户池中,进入“用户”标签页,手动创建一个用户(例如,dave)。首次登录时系统会要求我们设置密码和绑定 MFA 设备(如 Google Authenticator)。
第 2 步:创建 Cognito 身份池 (权限交换机)
  1. 再次进入 Cognito 控制台,切换到“联合身份池 (Federated Identities)”,点击“创建新的身份池”。
  2. 给身份池命名,然后展开“身份验证提供商”部分。
  3. 点击 “Cognito” 标签,输入我们上一步创建的用户池 ID应用客户端 ID
  4. 点击“创建池”。AWS 会提示我们为此身份池创建一个新的 IAM 角色。允许它创建!这个角色非常重要,它就是我们登录后最终“扮演”的角色。
第 3 步:配置 IAM 角色权限
  1. 进入 IAM 服务控制台,找到上一步为我们创建的那个 IAM 角色(通常名字里包含我们的身份池名称)。
  2. 这个角色默认权限很小。我们需要为它附加我们希望在 CLI 中拥有的权限策略。例如,如果我们希望拥有管理员权限,就附加 AdministratorAccess 策略。如果我们只想拥有 S3 的读写权限,就附加相应的策略。这是决定我们登录后能力范围的关键一步。
第 4 步:编写 CLI 登录脚本 (魔法发生的地方)

标准的 AWS CLI 没有内置 aws configure cognito 命令,所以我们需要一个小脚本来自动化这个登录流程。我们可以用任何我们喜欢的语言(Python, Bash, PowerShell)来写。

下面是一个使用 Python 和 Boto3 的简单示例 login.py

import boto3
import getpass
import configparser
import os# --- 配置Cognito信息 ---
USER_POOL_ID = 'us-east-1_xxxxxxxxx'  # 替换为我们的用户池ID
CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxx' # 替换为我们的用户池应用客户端ID
IDENTITY_POOL_ID = 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' # 替换为我们的身份池ID
REGION = 'us-east-1' # 替换为我们的区域
ROLE_ARN = 'arn:aws:iam::123456789012:role/Cognito_YourIdentityPoolAuth_Role' # 替换为身份池为我们创建的角色ARN
# -----------------------------def get_cognito_tokens(username, password):client = boto3.client('cognito-idp', region_name=REGION)try:# 第一步:发起认证resp = client.initiate_auth(ClientId=CLIENT_ID,AuthFlow='USER_PASSWORD_AUTH',AuthParameters={'USERNAME': username,'PASSWORD': password,})# 第二步:处理MFA挑战if 'ChallengeName' in resp and resp['ChallengeName'] == 'SOFTWARE_TOKEN_MFA':mfa_code = input("请输入我们的MFA验证码: ")resp = client.respond_to_auth_challenge(ClientId=CLIENT_ID,ChallengeName='SOFTWARE_TOKEN_MFA',Session=resp['Session'],ChallengeResponses={'USERNAME': username,'SOFTWARE_TOKEN_MFA_CODE': mfa_code})return resp['AuthenticationResult']['IdToken']except client.exceptions.NotAuthorizedException:print("错误:用户名或密码不正确。")return Noneexcept Exception as e:print(f"发生未知错误: {e}")return Nonedef get_aws_credentials(id_token):client = boto3.client('cognito-identity', region_name=REGION)# 用ID Token从身份池获取身份IDidentity_id_resp = client.get_id(IdentityPoolId=IDENTITY_POOL_ID,Logins={f'cognito-idp.{REGION}.amazonaws.com/{USER_POOL_ID}': id_token})identity_id = identity_id_resp['IdentityId']# 用身份ID获取临时AWS凭证creds_resp = client.get_credentials_for_identity(IdentityId=identity_id,Logins={f'cognito-idp.{REGION}.amazonaws.com/{USER_POOL_ID}': id_token})return creds_resp['Credentials']def update_aws_config(credentials):aws_config_path = os.path.expanduser('~/.aws/credentials')config = configparser.ConfigParser()if os.path.exists(aws_config_path):config.read(aws_config_path)profile_name = 'cognito-sso' # 我们可以自定义profile名称if not config.has_section(profile_name):config.add_section(profile_name)config.set(profile_name, 'aws_access_key_id', credentials['AccessKeyId'])config.set(profile_name, 'aws_secret_access_key', credentials['SecretAccessKey'])config.set(profile_name, 'aws_session_token', credentials['SessionToken'])with open(aws_config_path, 'w') as configfile:config.write(configfile)print(f"凭证已成功更新到profile '{profile_name}' 中。")print("现在我们可以使用 'aws s3 ls --profile cognito-sso' 来测试了。")if __name__ == "__main__":username = input("请输入用户名: ")password = getpass.getpass("请输入密码: ")id_token = get_cognito_tokens(username, password)if id_token:credentials = get_aws_credentials(id_token)update_aws_config(credentials)

如何使用这个脚本:

  1. 安装 boto3: pip install boto3
  2. 将脚本中顶部的配置信息替换为我们自己的 Cognito 和 IAM 信息。
  3. 运行脚本:python login.py
  4. 按照提示输入用户名、密码和 MFA 码。
  5. 脚本会自动获取临时凭证,并写入到 ~/.aws/credentials 文件的一个新的 profile 中(例如 [cognito-sso])。
  6. 之后,我们所有的 AWS CLI 命令都可以通过 --profile cognito-sso 来使用这些临时凭证,例如 aws s3 ls --profile cognito-sso
结论:自己动手,丰衣足食

虽然我们无法使用组织级的 IAM Identity Center,但这并不意味着我们必须在安全上妥协。通过组合 Cognito 用户池和身份池,我们成功地为自己构建了一个轻量、安全、且支持 MFA 的 CLI 登录解决方案。

这个方案不仅解决了我们的燃眉之急,更让我们深入理解了 AWS 身份联邦的强大能力。当我们需要为我们的应用程序或团队成员提供安全的 AWS 资源访问时,这套思路同样适用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912282.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912282.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

未来机器视觉软件将更注重成本控制,边缘性能,鲁棒性、多平台支持、模块优化与性能提升,最新版本opencv-4.11.0更新了什么

OpenCV 4.11.0 作为 4.10.0 的后续版本,虽然没有在提供的搜索结果中直接列出详细更新内容,但结合 OpenCV 4.10.0 的重大改进方向(发布于 2024 年 6 月),可以合理推断 4.11.0 版本可能延续了对多平台支持、模块优化和性能提升的强化。以下是基于 OpenCV 近期更新模式的推测…

小程序入门:数据请求全解析

在微信小程序开发中,数据请求是实现丰富功能的关键环节。本文将带你深入了解小程序数据请求的相关知识,包括请求限制、配置方法以及不同请求方式的实现,还会介绍如何在页面加载时自动请求数据,同时附上详细代码示例,让…

开源版gpt4o 多模态MiniGPT-4 实现原理详解

MiniGPT-4是开源的GPT-4的平民版。本文用带你快速掌握多模态大模型MiniGPT-4的模型架构、训练秘诀、实战亮点与改进方向。 1 模型架构全景:三层协同 📊 模型底部实际输入图像,经 ViT Q-Former 编码。蓝色方块 (视觉编码器):左侧…

Flutter基础(控制器)

第1步:找个遥控器(创建控制器)​ // 就像买新遥控器要装电池 TextEditingController myController TextEditingController(); ​​第2步:连上你的玩具(绑定到组件)​​ TextField(controller: myContro…

Spring Boot使用Redis常用场景

Spring Boot使用Redis常用场景 一、概述:Redis 是什么?为什么要用它? Redis(Remote Dictionary Server)是一个内存中的数据存储系统(类似一个“超级大字典”),它能存各种类型的数据…

CAD文件处理控件Aspose.CAD教程:在 C# 中将 DXF 文件转换为 SVG - AutoCAD C# 示例

概述 使用 C# 轻松将DXF文件转换为SVG。此转换可更好地兼容 Web 应用程序,并增强 CAD 图纸的视觉呈现效果。使用Aspose.CAD for .NET ,开发人员可以轻松实现此转换过程。该 SDK 提供强大的功能,使其成为 C# 开发人员的可靠选择。Aspose.CAD …

Gitee 持续集成与交付(CI/CD)篇

Gitee 持续集成与交付(CI/CD)篇 🚀 文章目录 Gitee 持续集成与交付(CI/CD)篇 🚀🎯 什么是 CI/CD?🌟 Gitee Go 介绍✨ 核心特性🎨 支持的技术栈 🚀…

深度学习:PyTorch卷积神经网络图像分类案例分享

本文目录: 一、了解CIFAR-10数据集二、案例之导包三、案例之创建数据集四、案例之搭建神经网络(模型构建)五、案例之编写训练函数(训练模型)六、案例之编写预测函数(模型测试) 前言:…

记录多功能按键第二种写法使用定时器周期间隔判断.

逻辑是通过定时器溢出周期进行判断按下次数 比如设置定时器溢出周期为500MS,每次溢出都会判断按键按下次数,如果下个周期前没有触发按下,则结束键值判断.并确定触发键值.清空按下次数标志.测试比一个定时器周期按下按键次数判断写法要稳定... 记录STM32实现多功能按键_stm32一…

【安卓Sensor框架-1】SensorService 的启动流程

内核启动后,首个用户空间进程init(pid1)解析init.rc配置文件,启动关键服务(如Zygote和ServiceManager)。 Zygote服务配置为/system/bin/app_process --zygote --start-system-server,后续用于孵…

centos网卡绑定参考

同事整理分享: 1. 加载 Bonding 模块 modprobe bonding 获取网卡名称 ip a 找到接了网线的网卡名称,记下。 3. 配置物理网卡 创建并编辑 /etc/sysconfig/network-scripts/ifcfg-ens36(ifcfg-后面的内容根据上面找到的具体网卡名称决定&#…

mbedtls ssl handshake error,res:-0x2700

用LinkSDK.c连接第三方云平台出现现象 解决方案: 在_tls_network_establish函数中加入 mbedtls_ssl_conf_authmode(&adapter_handle->mbedtls.ssl_config, MBEDTLS_SSL_VERIFY_NONE);原因解释:用连接方式是不用证书认证/跳过服务端认证。

Spring Security 的方法级权限控制是如何利用 AOP 的?

Spring Security 的方法级权限控制是 AOP 技术在实际应用中一个极其强大的应用典范。它允许我们以声明式的方式保护业务方法,将安全规则与业务逻辑彻底解耦。 核心思想:权限检查的“门卫” 你可以把 AOP 在方法级安全中的作用想象成一个尽职尽责的“门…

一键内网穿透,无需域名和服务器,自动https访问

cloudflare能将内网web转为外网可访问的地址。(这和apiSQL有点类似,apiSQ可以将内网数据库轻松转换为外网的API,并且还支持代理内网已有API,增强安全增加API Key,以https访问等等) 但Cloudfalre tunnel这个…

Sentinel(二):Sentinel流量控制

一、Sentinel 流控规则基本介绍 1、Snetinel 流控规则配置方式 Sentinel 支持可视化的流控规则配置,使用非常简单;可以在监控服务下的“簇点链路” 或 “流控规则” 中 给指定的请求资源配置流控规则;一般推荐在 “簇点链路” 中配置流控规则…

支持PY普冉系列单片机调试工具PY32linK仿真器

PY32 Link是专为 ‌PY32系列ARM-Cortex内核单片机‌(如PY32F002A/030/071/040/403等)设计的仿真器,支持全系列芯片的‌调试和仿真‌功能。‌开发环境兼容性‌支持主流IDE:‌Keil MDK‌ 和 ‌IAR Embedded Workbench‌,…

深入解析Python多服务器监控告警系统:从原理到生产部署

深入解析Python多服务器监控告警系统:从原理到生产部署 整体架构图 核心设计思想 无代理监控:通过SSH直接获取数据,无需在目标服务器安装代理故障隔离:单台服务器故障不影响整体监控多级检测:网络层→资源层→服务层层…

JUC:10.线程、monitor管程、锁对象之间在synchronized加锁的流程(未完)

一、monitor管程工作原理: 首先,synchronized是一个对象锁,当线程运行到某个临界区,这个临界区使用synchronized对对象obj进行了上锁,此时底层发生了什么? 1.当synchronized对obj上锁后,synch…

Elasticsearch(ES)分页

Elasticsearch(简称 ES)本身不适合传统意义上的“深分页”,但提供了多种分页方式,每种适用不同场景。我们来详细讲解: 一、基本分页(from size) 最常用的分页方式,类似 SQL 的 LIM…

原生微信小程序:用 `setData` 正确修改数组中的对象项状态(附实战技巧)

📌 背景介绍 在微信小程序开发中,我们经常需要修改数组中某个对象的某个字段,比如: 列表中的某一项展开/收起多选状态切换数据列表中的临时标记等 一个常见的场景是: lists: [{ show: true }, { show: true }, { s…