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

使用预签名URL上传S3桶报错:提供的AWS访问密钥不存在

问题解决:预签名URL上传S3报InvalidAccessKeyId错误

核心原因

你手动从EC2元数据获取IAM角色临时凭证时,漏掉了SessionToken。ASIA开头的AccessKeyId是AWS临时凭证,必须配合SessionToken一起使用,缺少它会导致S3验证失败,抛出InvalidAccessKeyId错误。

修复步骤

1. 修改凭证获取函数,补充SessionToken

更新get_aws_creds函数,从元数据中提取并返回SessionToken(注意补上缺失的requests导入):

import requests
import json
import boto3
import pydantic
from botocore.exceptions import ClientError
from botocore.client import Config
import datetime


URL = "http://169.254.169.254/latest/meta-data/iam/security-credentials/my-iam-role-s3"
access_key = ""
secret_key = ""
session_token = ""  # 新增全局变量存储SessionToken

def get_aws_creds():
    global access_key
    global secret_key
    global session_token
    try:
        response = requests.get(URL)
        response.raise_for_status()
        json_response = json.loads(response.text)
        access_key = json_response["AccessKeyId"]
        secret_key = json_response["SecretAccessKey"]
        session_token = json_response["Token"]  # 新增:获取SessionToken
    except requests.exceptions.HTTPError as err:
        print(err)
        raise SystemExit(err)
    return access_key, secret_key, session_token

2. 初始化S3客户端时传入SessionToken

修改get_pre_signed_upload_URL函数,在创建boto3客户端时添加aws_session_token参数:

def get_pre_signed_upload_URL(uuid :str):
    global access_key
    global secret_key
    global session_token

    if (access_key == "" or secret_key == "" or session_token == ""):
        access_key, secret_key, session_token = get_aws_creds()
    s3_client = boto3.client(
        's3',
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key,
        aws_session_token=session_token,  # 新增:传入SessionToken
        region_name="us-west-1",
        config=Config(signature_version='s3v4'))
    try:
        response = s3_client.generate_presigned_post(
            Bucket=bucket_name,
            Key=uuid,
            ExpiresIn=50
             )
    except ClientError as e:
        return None
    return response

3. 验证修复效果

修复后,客户端获取的fields里会新增x-amz-security-token字段,包含SessionToken值,此时再用curl上传就能正常通过S3的验证。

更推荐的优化方案

你完全不需要手动请求元数据获取凭证,boto3会自动从EC2实例的IAM角色中加载临时凭证,代码可以大幅简化,避免手动处理凭证的错误:

import boto3
from botocore.exceptions import ClientError
from botocore.client import Config

bucket_name = "my-bucket-name-s3"

def get_pre_signed_upload_URL(uuid :str):
    # boto3自动从EC2角色获取凭证,无需手动指定密钥
    s3_client = boto3.client(
        's3',
        region_name="us-west-1",
        config=Config(signature_version='s3v4'))
    try:
        response = s3_client.generate_presigned_post(
            Bucket=bucket_name,
            Key=uuid,
            ExpiresIn=50
             )
    except ClientError as e:
        return None
    return response

这种方式会自动处理凭证的轮换,比手动请求元数据更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:47:04