如何使用 AWS 访问 S3 资源 SDK.NET 通过当前用户的安全密钥、访问密钥和 IAM 角色从元数据中找到的会话令牌



我想访问S3 bucket。但我的客户不想通过Enviroment变量传递安全密钥和访问密钥。他正在AWS的EC2实例上运行我们的代码。因此,他希望编写代码,以便使用他的IAM角色自动查找凭据。

我可以使用元数据信息获取AWS安全密钥、访问密钥和安全令牌,但不幸的是,当我使用这些凭据时,我会收到一条错误消息,在AWS中找不到密钥。我试着打http://169.254.169.254/latest/meta-data/iam/security-credentials/MyRole获取AWS安全密钥、访问密钥和会话令牌。有了这3,我正在写下面的代码,它正在爆炸:

var crede = new SessionAWSCredentials(_accessKey, _secretKey, _token);
var s3Client = new AmazonS3Client(_accessKey, _secretKey, _token, config);
var response = await s3Client.GetObjectAsync(request);
return response.ResponseStream;

The specified key does not exist., stack:   at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionStream(IRequestContext requestContext, IWebResponseData httpErrorResponse, HttpErrorResponseException exception, Stream responseStream)
at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionAsync(IExecutionContext executionContext, HttpErrorResponseException exception)
at Amazon.Runtime.Internal.ExceptionHandler`1.HandleAsync(IExecutionContext executionContext, Exception exception)
at Amazon.Runtime.Internal.ErrorHandler.ProcessExceptionAsync(IExecutionContext executionContext, Exception exception)
at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
at awstest.Program.Main(String[] args) in C:UsersVikasKumarsourcereposConsoleApp1awstestProgram.cs:line 99

终于能够解决这个问题:

private static ImmutableCredentials FetchCredentials()
{
var securityCredentials = EC2InstanceMetadata.IAMSecurityCredentials;
if (securityCredentials == null)
throw new AmazonServiceException("Unable to get IAM security credentials from EC2 Instance Metadata Service.");
string firstRole = null;
foreach (var role in securityCredentials.Keys)
{
firstRole = role;
break;
}
if (string.IsNullOrEmpty(firstRole))
throw new AmazonServiceException("Unable to get EC2 instance role from EC2 Instance Metadata Service.");
var metadata = securityCredentials[firstRole];
if (metadata == null)
throw new AmazonServiceException("Unable to get credentials for role "" + firstRole + "" from EC2 Instance Metadata Service.");
return new ImmutableCredentials(metadata.AccessKeyId, metadata.SecretAccessKey, metadata.Token);
}

调用FetchCredentials:

var credentials = FetchCredentials();

var config = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.GetBySystemName("ap-southeast-2")
};

var s3Client = new AmazonS3Client(credentials.AccessKey, credentials.SecretKey, credentials.Token, config);
Console.Write("temp credentials created s3 client.");
var request = new GetObjectRequest
{
BucketName = "opensparkzstorage",
Key = "qa/outbound/mys3filename.csv"
};
var listReq = new ListObjectsRequest
{
BucketName = "mys3bucketname"
};
var response = await s3Client.ListObjectsAsync(listReq);
foreach (S3Object entry in response.S3Objects)
{
Console.Write(entry.Key);
}

最新更新