我有一个 API 调用的 lambda,它生成签名的 getObject 和 putObject URL。我的受限存储桶(包含 zip 文件)上的 GET 和 PUT 工作正常,但我的公共存储桶(包含图像)上的 PUT 返回“SignatureDoesNotMatch”错误。公共存储桶上没有 GET,直接引用该存储桶中的图像。我需要额外的配置来 PUT 到公共存储桶上吗?我已经尝试给予我能想到的最慷慨的权限。
编辑:我最终不得不将特定图像 MIME 类型发送到生成签名 URL 的端点。不幸的是,image/* 没有用。
签名 URL 生成(由 getSignedImgUploadUrl 调用)
let params = {
Bucket: "public-bucket",
Key: `${folder}/${key}.jpg`, // Ideally without extension
Expires: 30,
ContentType: "image/jpeg", // Ideally image/*
ACL: "public-read" // Tried with and without this
};
let url = s3.getSignedUrl("putObject", params);
let result = {
signedUrl: url,
key: key
};
return result;
使用签名网址
public uploadImg(folder: string, file: any, key: string): Observable<any> {
return this._spinnerService.spinObservable(
new Observable(subscriber => {
this.getSignedImgUploadUrl(folder, key)
.subscribe(result => {
// put to signedUrl fails with 403 SignatureDoesNotMatch
this._httpClient.put(result["signedUrl"], file, { headers: { "x-amz-acl": "public-read" } })
.subscribe(() => {
subscriber.next(result["key"]);
subscriber.complete();
}, err => {
console.log(err);
subscriber.error(err);
});
}, err => {
console.log(err);
subscriber.error(err);
});
}));
}
Lambda 角色
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::restricted-bucket/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "s3:*", (Ideally just getObject/putObject)
"Resource": "arn:aws:s3:::public-bucket/*"
}
]
}
公共存储桶政策
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::public-bucket/*"
},
// Also tried adding s3:* for the lambda role without luck
{
"Sid": "Stmt1624999949645",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::account:role/service-role/lambda-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::public-bucket/*"
}
]
}
答案 0 :(得分:1)
根据 OP 的评论,明确发送 Content-Type
HTTP 标头有效。有时需要此标头的原因是 HTTP 客户端无法从 PUT 负载正确推断 MIME 类型。