You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:11:05