升级AWS SDK v2后无法向S3存储桶上传文件求助
解决AWS SDK v2升级后S3上传凭证问题
问题分析
升级AWS SDK v2至2月19日版本后,S3上传失败报错no EC2 IMDS role found,核心原因是新版本SDK的凭证链逻辑发生变更:默认情况下会优先尝试通过EC2实例元数据服务(IMDS)获取凭证,即便本地~/.aws/credentials文件存在,也可能因加载优先级或配置问题未被正确读取,导致凭证获取失败。旧版本SDK对本地凭证的优先级更高,因此之前能正常运行。
解决方案
1. 显式指定共享凭证提供者
在加载SDK配置时,明确指定使用本地共享凭证文件,确保SDK优先读取本地凭证,同时添加错误处理(原代码忽略了配置加载错误,这是潜在隐患):
func UploadFileInS3Bucket(fileContent io.Reader, filePath, bucketName, contentType string) (*manager.UploadOutput, error) { cfg, err := awsconfig.LoadDefaultConfig(context.TODO(), awsconfig.WithRegion("us-west-1"), // 显式指定使用default profile的共享凭证 awsconfig.WithCredentialsProvider(credentials.NewSharedCredentialsProvider("", "default")), ) // 必须处理配置加载错误 if err != nil { return nil, fmt.Errorf("failed to load SDK config: %w", err) } client := s3.NewFromConfig(cfg) uploader := manager.NewUploader(client) cacheExpireTime := time.Now().AddDate(1, 0, 0) cacheMaxAgeSecs := "max-age=31556926" // seconds in 1 year uploadResp, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(filePath), Body: fileContent, ContentType: aws.String(contentType), Expires: &cacheExpireTime, CacheControl: aws.String(cacheMaxAgeSecs), }) return uploadResp, err }
2. 验证本地凭证文件有效性
- 检查
~/.aws/credentials文件格式是否正确,需符合INI格式:[default] aws_access_key_id = YOUR_ACCESS_KEY aws_secret_access_key = YOUR_SECRET_KEY - 调整文件权限,确保仅当前用户可读(Linux/macOS执行命令):
chmod 600 ~/.aws/credentials
3. 自定义凭证链优先级(可选)
如果需要更灵活的凭证获取逻辑,可以自定义凭证链,将共享凭证放在最前面:
cfg, err := awsconfig.LoadDefaultConfig(context.TODO(), awsconfig.WithRegion("us-west-1"), awsconfig.WithCredentialsProvider(credentials.NewChainCredentials( []credentials.Provider{ // 优先使用共享凭证 &credentials.SharedCredentialsProvider{Profile: "default"}, // 其次使用环境变量凭证 &credentials.EnvProvider{}, }, )), )
4. 调试凭证加载过程
添加日志验证凭证是否正确加载(注意不要泄露敏感信息):
creds, err := cfg.Credentials.Retrieve(context.TODO()) if err != nil { return nil, fmt.Errorf("failed to retrieve credentials: %w", err) } // 仅打印AccessKeyID前缀用于验证,避免泄露完整密钥 log.Printf("loaded credentials for user: %s***", creds.AccessKeyID[:4])
内容的提问来源于stack exchange,提问作者Amandeep kaur
相关产品推荐
相关产品推荐

