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

使用Lambda生成的预签名URL上传Amazon S3时遇403签名不匹配错误

使用Lambda生成的S3预签名URL上传文件时出现403 Forbidden(SignatureDoesNotMatch)错误排查

问题场景

通过Lambda生成S3预签名PUT URL,返回给用户后,用户使用Postman调用该URL上传文件时触发403 Forbidden错误,错误详情如下:

return (<Code>SignatureDoesNotMatch</Code>
)
return (<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
)

已完成的配置与代码实现

配置项

  • 已为Lambda执行角色附加S3全访问权限策略
  • Lambda部署在VPC私有网络中
  • S3 Bucket已配置允许Lambda访问

代码实现

方式一:使用getSignedUrl生成预签名URL

import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
import { PutObjectCommandInput, S3Client, PutObjectCommand } from '@aws-sdk/client-s3'

const Bucket = process.env.BUCKET_NAME!

const client = new S3Client({
  region: process.env.AWS_REGION!,
})

const params: PutObjectCommandInput = {
    Bucket,
    Key: `xxxxx/yyyyy`
  }

return await getSignedUrl(client, new PutObjectCommand(params), { expiresIn: 3000 })

方式二:手动实例化S3RequestPresigner生成预签名URL

import { S3RequestPresigner } from '@aws-sdk/s3-request-presigner'
import { parseUrl } from '@aws-sdk/url-parser'
import { Hash } from '@aws-sdk/hash-node'
import { HttpRequest } from '@aws-sdk/protocol-http'
import { S3Client } from '@aws-sdk/client-s3'

const Bucket = process.env.BUCKET_NAME

const client = new S3Client({
  region: process.env.AWS_REGION!,
})

const s3ObjectUrl = parseUrl(`https://${Bucket}.s3.${process.env.AWS_REGION}.amazonaws.com/xxxxx/yyyyy`)
const presigner = new S3RequestPresigner({
    credentials: { accessKeyId: process.env.AWS_ACCESS_KEY_ID!, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY! },
    region: process.env.AWS_REGION!,
    sha256: Hash.bind(null, 'sha256'),
  })
return await presigner.presign(new HttpRequest({ ...s3ObjectUrl, method: 'PUT' }), { expiresIn: 3000 })

排查思路

1. 确保请求参数完全匹配

  • 上传时必须使用PUT方法,与预签名生成时的请求方法一致
  • 上传的对象Key必须和预签名中指定的xxxxx/yyyyy完全一致,包括大小写、路径格式
  • 如果上传时设置了Content-Type,预签名生成时必须在PutObjectCommand参数中添加相同的Content-Type字段,否则签名验证会失败

2. 检查Lambda的VPC网络连通性

  • 如果Lambda在私有子网:
    • 要么配置NAT网关,确保Lambda能访问公网S3端点
    • 要么配置S3网关端点(Gateway Endpoint),并确认VPC路由表已添加指向该端点的路由,同时端点策略允许Lambda角色访问目标Bucket
  • 网络不通会导致预签名生成时的凭证或签名逻辑异常,间接引发签名不匹配

3. 规范凭证使用与SDK版本

  • 方式二中硬编码AWS凭证的做法不推荐,改用Lambda执行角色的临时凭证(即方式一的实现),避免硬编码凭证过期、权限不符或泄露
  • 确保所有@aws-sdk相关依赖包版本一致,版本差异可能导致签名算法不兼容

4. 验证S3 Bucket策略与权限

  • 检查Bucket策略是否明确允许s3:PutObject操作,资源路径需匹配arn:aws:s3:::${Bucket}/xxxxx/yyyyy
  • 确认Lambda执行角色的权限策略中,包含对目标Bucket的s3:PutObject权限(即使是全访问策略,也需确认资源范围覆盖目标对象路径)

5. 检查时间同步

  • 预签名URL的签名依赖精准时间,如果Lambda所在环境的系统时间与AWS服务器时间偏差超过5分钟,会触发签名验证失败,需确认Lambda的时间同步正常

内容的提问来源于stack exchange,提问作者Take

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:20:28