c# - 如何使用签名版本 4 生成 AWS S3 预签名 URL
问题描述
我正在使用 AWSSDK.S3 (3.3.31.11) 在 C# .NET Core 2.0 API 控制器类中生成预签名 URL。生成的 URL 旨在供客户端 Angular 应用程序用于将文件上传到使用 SSE-KMS 加密的 S3 存储桶。尽管 S3Client 报告 SignatureMethod 为“HmacSHA256”且 SignatureVersion 为“4”,但当我尝试使用预签名 URL 上传文件时,我收到一条错误消息,指出“使用 AWS KMS 托管密钥指定服务器端加密的请求需要 AWS 签名第 4 版。”
S3Client 作为对控制器类的依赖项被注入。对象的实例化由 .NET Core DI 框架使用 config.json 文件中的配置设置进行管理:
{
...
"AWS": {
"Profile": "default",
"Region": "us-east-1"
}
...
}
我正在使用 curl 测试预签名的 URL:
curl -H "Content-Type: application/pdf" -H "x-amz-server-side-encryption: aws:kms" -H "x-amz-server-side-encryption-aws-kms-key-id: {kms-key-id}" -k -T "filename.pdf" "https://mybucketname.s3.amazonaws.com/filename.pdf?AWSAccessKeyId={keyid}&Expires={expires}&x-amz-security-token={token}&Signature={signature}"
我发现如果我不包含“Content-Type”标头,我会收到“SignatureDoesNotMatch”错误代码,而不是“InvalidArgument”错误。
此过程以前在为 S3 存储桶使用默认 AES-256 加密时一直有效,只是在转换为 SSE-KMS 时我遇到了这个问题。
// Controller Class
private readonly IAmazonS3 _s3Client;
public MyController(IAmazonS3 s3Client)
{
_s3Client = s3Client;
}
[HttpPost]
public async Task<IActionResult> GetPreSignedUrl([FromBody] FileInfoDto fileInfo)
{
...
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = fileInfo.name,
Verb = HttpVerb.PUT,
ContentType = fileInfo.contentType,
Expires = DateTime.Now.AddMinutes(5),
ServerSideEncryptionKeyManagementServiceKeyId = keyId,
ServerSideEncryptionMethod = ServerSideEncryptionMethod.AWSKMS
};
try
{
url = _s3Client.GetPreSignedURL(request);
}
...
}
// Startup Class
public void ConfigureServices(IServiceCollection services)
{
...
services.AddDefaultAWSOptions(_config.GetAWSOptions());
services.AddAWSService<IAmazonS3>();
...
}
使用 curl 和控制器方法生成的预签名 URL 上传文件时,我收到“InvalidArgument”响应错误代码和消息“使用 AWS KMS 托管密钥指定服务器端加密的请求需要 AWS 签名版本 4。 " 但是,S3Client 报告 SignatureVersion 为“4”。
为了使用签名版本 4 生成预签名 URL,我应该做些什么不同的事情?
解决方案
尽管 s3Client 将 Signature Version 报告为“4”,但添加到 ConfigureServices 方法的以下行解决了问题并导致生成符合 Signature Version 4 的预签名 URL:
AWSConfigsS3.UseSignatureVersion4 = true;
生成的预签名 URL 如下:
https://mybucketname.s3.amazonaws.com/filename.pdf?X-Amz-Expires=1800&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={credential}/20190127/us-east-1/s3/aws4_request&X-Amz-Date={date}&X-Amz-SignedHeaders=content-type;host;x-amz-server-side-encryption&X-Amz-Signature={signature}
推荐阅读
- python - Python使用外部程序加密
- python - 定义类函数的好方法,这些函数都调用具有不同参数的相同函数
- asp.net-mvc - 保存到 localdb 时记录以奇怪的顺序更新 - LINQ
- java - 使用 jersey2.1 休息服务器返回列表作为 json 给出错误?
- vue.js - 当 prop 具有 get() 和 set() 时,使用 :model.sync 进行两种数据绑定
- python - 从 python defaultdict(list) 中过滤/删除不存在键的值?
- python - python中的Apache Beam:如何触发空窗口的警报
- javascript - 如何在 javascript 中连续播放生成的声音?
- javascript - 在javascript中递归创建事件
- php - 如何在 wordpress 自定义插件中重定向