生成S3预签名Post URL遇‘未提供AWSAccessKey’错误求助
解决S3预签名Post请求的AccessDenied(No AWSAccessKey was presented)问题
问题场景
使用boto3生成S3预签名Post URL后,返回的fields中未包含AWSAccessKeyId字段,发起POST请求时收到No AWSAccessKey was presented的权限错误。
生成预签名Post的Python代码
def generate_pre_signed_upload_url(content_type: str, expiration: int, fields, bucket_name: str, object_name: str): try: config = Config(signature_version='s3v4') s3 = boto3.client("s3", region_name='us-west-2', config=config) return s3.generate_presigned_post( Bucket=bucket_name, Key=object_name, Fields=fields, ExpiresIn=expiration, Conditions=[{"Content-Type": content_type}], ) except Exception as e: raise e
代码返回结果
{ "url": "https://sandbox-taxservice-s3bucket-s3bucket6575f0a6-19dl1xpyc3fzo.s3.amazonaws.com/", "fields": { "key": "xxxxxxxxxxxxx", "x-amz-algorithm": "AWS4-HMAC-SHA256", "x-amz-credential": "xxxxxxxxx", "x-amz-date": "xxxxxx", "x-amz-security-token": "xxxxxx", "policy": "xxxxxxxx", "x-amz-signature": "xxxxxxx" } }
错误响应
<?xml version="1.0" encoding="UTF-8"?> <Error> <Code>AccessDenied</Code> <Message>No AWSAccessKey was presented.</Message> <RequestId>354BCDQHZ4NB8Y4D</RequestId> <HostId>aBM0WkvvrVg9H+Q2H826rHA/bPhxvSGGEg5HKbkxEHwbzybN0p0dhbR4F8np/ovKHJlx9Cwgrgc=</HostId> </Error>
解决方案
1. 规范请求提交方式
S3预签名Post要求所有fields参数作为表单字段提交,需满足:
- 请求方法必须为
POST - 表单
enctype设置为multipart/form-data - 完整传递
fields中的所有键值对(V4签名模式下,x-amz-credential已包含访问密钥ID,无需单独的AWSAccessKeyId字段)
2. 校验IAM权限
确保生成预签名URL的IAM身份(用户/角色)拥有:
s3:PutObject权限(针对目标Bucket和指定Key)- 若使用临时凭证,需确认凭证未过期且权限范围覆盖目标操作
3. 修正Conditions参数冲突
如果调用函数时传入的fields已包含Content-Type字段,需删除Conditions中的对应条目,避免签名验证冲突。示例调整:
return s3.generate_presigned_post( Bucket=bucket_name, Key=object_name, Fields=fields, ExpiresIn=expiration, # 若fields已含Content-Type,移除此行 # Conditions=[{"Content-Type": content_type}], )
4. 临时 workaround:手动添加AWSAccessKeyId
若上述方法无效,可在调用函数时传入的fields中手动添加该字段:
fields = { # 原有字段... "AWSAccessKeyId": "你的IAM访问密钥ID" }
注意:此方法仅作为临时修复,V4签名模式下优先通过规范请求方式解决问题。
内容的提问来源于stack exchange,提问作者tomvonheill
相关产品推荐
相关产品推荐

