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

如何使用C#/.Net下载AWS S3文件并解决角色权限导致的Access Denied错误

错误根因

你当前直接使用IAM用户的永久密钥初始化S3客户端,没有切换到拥有S3对象访问权限的角色,所以触发Access Denied报错,和网页端需要切换角色才能下载的逻辑一致。

代码修改步骤
  • 先安装依赖NuGet包:除已有的AWSSDK.S3外,额外安装AWSSDK.SecurityToken包,用于调用AWS STS服务完成角色切换获取临时访问凭证
  • 先通过STS接口调用AssumeRole方法,获取目标角色的临时访问密钥、会话令牌
  • 使用返回的临时凭证初始化AmazonS3Client,再发起S3对象下载请求
  • 修正原代码中二进制文件读取逻辑:图片为二进制资源,不可用StreamReader按文本读取,直接将响应流写入本地文件即可避免文件损坏
完整修改后代码
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class GetObjectTest
    {
        private const string bucketName = "My_Bucket_Name"; // 替换为实际桶名
        private const string keyName = "123/456/789.jpg"; // 替换为实际对象路径
        private const string targetRoleArn = "arn:aws:iam::你的账号ID:role/你的角色名称"; // 替换为有权限的角色ARN
        private const string roleSessionName = "S3DownloadSession"; // 自定义会话名称,可随意填写
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; // 替换为实际桶区域
        private static IAmazonS3 s3Client;

        static string accessKey = "***AccessKey***";   // 替换为你的IAM用户访问密钥
        static string secretKey = "***SecretKey***"; // 替换为你的IAM用户私密密钥

        public static void Main()
        {
            // 先切换角色获取临时凭证
            var credentials = AssumeTargetRoleAsync().GetAwaiter().GetResult();
            // 使用临时凭证初始化S3客户端
            s3Client = new AmazonS3Client(credentials, bucketRegion);
            ReadObjectDataAsync().Wait();
        }

        /// <summary>
        /// 调用STS服务切换角色,获取临时凭证
        /// </summary>
        static async Task<Credentials> AssumeTargetRoleAsync()
        {
            using var stsClient = new AmazonSecurityTokenServiceClient(accessKey, secretKey, bucketRegion);
            var assumeRoleRequest = new AssumeRoleRequest
            {
                RoleArn = targetRoleArn,
                RoleSessionName = roleSessionName,
                // 可根据需要设置临时凭证有效期,默认3600秒,最长可设置为角色允许的最大时长
                DurationSeconds = 3600
            };
            var response = await stsClient.AssumeRoleAsync(assumeRoleRequest);
            return response.Credentials;
        }

        static async Task ReadObjectDataAsync()
        {
            GetObjectRequest request = new GetObjectRequest
            {
                 BucketName = bucketName,
                 Key = keyName
            };
            using (GetObjectResponse response = await s3Client.GetObjectAsync(request))
            using (Stream responseStream = response.ResponseStream)
            using (var fileStream = new FileStream(Path.GetFileName(keyName), FileMode.Create, FileAccess.Write))
            {
                string title = response.Metadata["x-amz-meta-title"];
                string contentType = response.Headers["Content-Type"];
                Console.WriteLine("Object metadata, Title: {0}", title);
                Console.WriteLine("Content type: {0}", contentType);

                // 直接将响应流写入本地文件,适配二进制图片资源
                await responseStream.CopyToAsync(fileStream);
                Console.WriteLine($"文件已下载至:{Path.GetFullPath(Path.GetFileName(keyName))}");
             }
        }
    }
}
前置权限校验说明
  • 你使用的原始IAM用户必须拥有sts:AssumeRole权限,允许扮演目标角色
  • 目标角色的信任策略中必须添加你的IAM用户ARN作为可信任实体,允许该用户切换角色
  • 目标角色的权限策略中必须配置对应S3桶、对象路径的s3:GetObject访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 03:36:05