Lambda中用Cognito临时凭证生成S3预签名URL遇权限问题求助
解决方法
1. 显式传入Cognito临时凭证初始化S3Client
问题核心是AWS SDK默认会优先使用Lambda执行角色的凭证链,而非你手动获取的Cognito临时凭证。必须在创建S3Client实例时明确指定credentials参数,强制使用Cognito返回的临时凭证。
示例代码:
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; // 从Cognito身份池获取临时凭证的逻辑(替换为你的实际实现) const fetchCognitoTempCreds = async () => { const authResponse = await yourCognitoAuthFlow(); return { accessKeyId: authResponse.Credentials.AccessKeyId, secretAccessKey: authResponse.Credentials.SecretKey, sessionToken: authResponse.Credentials.SessionToken }; }; export const handler = async (event) => { const cognitoCreds = await fetchCognitoTempCreds(); // 关键:显式传入Cognito凭证,不依赖默认凭证链 const s3Client = new S3Client({ region: "us-east-1", // 替换为你的存储桶区域 credentials: cognitoCreds }); const getObjCmd = new GetObjectCommand({ Bucket: "your-bucket-name", Key: "target-object-key" }); const signedUrl = await getSignedUrl(s3Client, getObjCmd, { expiresIn: 3600 }); return { signedUrl }; };
2. 强制禁用默认凭证链(可选,进一步确保)
如果想彻底避免SDK自动加载Lambda角色凭证,可以通过credentialDefaultProvider强制指定凭证来源:
const s3Client = new S3Client({ region: "us-east-1", credentials: cognitoCreds, credentialDefaultProvider: () => async () => cognitoCreds });
3. 验证Cognito角色权限
确认Cognito身份池绑定的自定义角色拥有生成预签名URL所需的权限,比如下载URL需要s3:GetObject,上传URL需要s3:PutObject,且资源路径匹配目标S3对象:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::your-bucket-name/allowed-path/*" } ] }
4. 排除Lambda角色干扰
临时移除Lambda执行角色上的S3相关权限,测试预签名URL是否能正常生效——如果此时URL可用,说明已经成功切换到Cognito凭证的权限。
内容的提问来源于stack exchange,提问作者Prasanjeet Mohanty
相关产品推荐
相关产品推荐

