如何在AWS SDK 2.x中结合AWS SSO获取S3对象
使用AWS SSO结合aws-sdk v2.x访问S3对象
问题描述
我在Node.js应用中使用aws-sdk (2.x)获取S3对象的代码能正常运行,但代码里硬编码了accessKeyId和secretAccessKey。我的本地已经配置好AWS SSO,配置信息如下:
[profile AWS-XXX] sso_start_url = https://XXX.XXX.com/start/# sso_region = XXXXX sso_account_id = XXXXXXXXXX sso_role_name = XXXAdministratorAccess region = XXXX
希望改用AWS SSO来访问S3,不再硬编码密钥。
原运行正常的代码:
const AWS = require("aws-sdk"); S3 = new AWS.S3({ accessKeyId: 'actual_accessKeyId', secretAccessKey: 'actual_secretAccessKey', region: 'region', signatureVersion: "v4", }); const listBucketContent = (filePath, bucketName) => { const params = { Bucket: bucketName, Prefix: filePath }; return S3.listObjects(params).promise(); };
解决方案
aws-sdk v2.x本身不原生支持解析SSO配置文件,可通过以下两种方式实现:
方式一:利用AWS CLI凭证进程(推荐)
- 更新AWS配置文件
在~/.aws/config的目标profile中添加credential_process配置,让SDK通过CLI获取SSO临时凭证:
[profile AWS-XXX] sso_start_url = https://XXX.XXX.com/start/# sso_region = XXXXX sso_account_id = XXXXXXXXXX sso_role_name = XXXAdministratorAccess region = XXXX credential_process = aws sso get-role-credentials --profile AWS-XXX --role-name XXXAdministratorAccess --account-id XXXXXXXXXX --query 'RoleCredentials' --output json
- 修改Node.js代码
移除硬编码的密钥,通过SharedIniFileCredentials指定profile,SDK会自动调用上述凭证进程获取SSO凭证:
const AWS = require("aws-sdk"); // 基于指定的SSO profile初始化S3客户端 const S3 = new AWS.S3({ signatureVersion: "v4", credentials: new AWS.SharedIniFileCredentials({ profile: "AWS-XXX" }) }); const listBucketContent = (filePath, bucketName) => { const params = { Bucket: bucketName, Prefix: filePath }; return S3.listObjects(params).promise(); };
- 提前完成SSO登录
在运行Node.js应用前,先通过AWS CLI完成SSO登录(只需执行一次,凭证会缓存到本地):
aws sso login --profile AWS-XXX
方式二:手动获取SSO临时凭证
如果无法依赖AWS CLI,可通过代码调用AWS SSO API获取临时凭证,再传入SDK:
const AWS = require("aws-sdk"); const sso = new AWS.SSO({ region: "XXXXX" }); // 获取SSO令牌(需提前完成SSO授权,令牌可从~/.aws/sso/cache/下的文件读取) async function getSSOCredentials() { const tokenResponse = await sso.getRoleCredentials({ roleName: "XXXAdministratorAccess", accountId: "XXXXXXXXXX", accessToken: "YOUR_SSO_ACCESS_TOKEN" }).promise(); return { accessKeyId: tokenResponse.roleCredentials.accessKeyId, secretAccessKey: tokenResponse.roleCredentials.secretAccessKey, sessionToken: tokenResponse.roleCredentials.sessionToken, expiration: tokenResponse.roleCredentials.expiration }; } // 初始化S3客户端 async function initS3() { const credentials = await getSSOCredentials(); return new AWS.S3({ region: "XXXX", signatureVersion: "v4", credentials: credentials }); } // 使用示例 async function main() { const s3 = await initS3(); const content = await s3.listObjects({ Bucket: "your-bucket", Prefix: "your-path" }).promise(); console.log(content); } main();
注意:此方法需要自行处理SSO令牌的获取与缓存,相对繁琐,优先推荐方式一。
内容的提问来源于stack exchange,提问作者micronyks
相关产品推荐
相关产品推荐

