我有无服务器的AWS Lambda,它将通过预签名的URL将对象获取/放到加密的S3存储桶中。 getObject工作完美。一旦加密存储桶并且我不明白为什么,putObject就会产生SignatureDoesNotMatch
错误。我玩过标题等,但仍然无法正常使用。以下代码/政策:
lambda
const generatepresignedurl = (req, res, callback) => {
var fileurls = [];
const body = JSON.parse(req.body);
const theBucket = body['theBucket'];
const theKey = body['theKey'];
const theContentType = body['theContentType'];
const theOperation = body['theOperation'];
/*setting the presigned url expiry time in seconds, also check if user making the request is an authorized user
for your app (this will be specific to your app’s auth mechanism so i am skipping it)*/
const signedUrlExpireSeconds = 60 * 60;
if (theOperation == 'getObject') {
var params = {
Bucket: theBucket,
Key: theKey,
Expires: signedUrlExpireSeconds
};
} else {
var params = {
Bucket: theBucket,
Key: theKey,
Expires: signedUrlExpireSeconds,
ACL: 'bucket-owner-full-control',
ContentType: theContentType,
ServerSideEncryption: 'AES256'
};
}
s3.getSignedUrl(theOperation, params, function (err, url) {
if (err) {
console.log('Error Getting Presigned URL from AWS S3');
// callback(null, ({ success: false, message: 'Pre-Signed URL error', urls: fileurls }));
callback(null, {error: err});
}
else {
fileurls[0] = url;
console.log('Presigned URL: ', fileurls[0]);
callback(null, { success: true, message: 'AWS SDK S3 Pre-signed urls generated successfully.', urls: fileurls });
}
});
}
呼叫代码在这里:
生成预签名网址
Function callStandAloneAWSService(lambda As String, request As String, contentType As String) As String
Dim httpserver As New MSXML2.XMLHTTP
With httpserver
Dim theURL As String
theURL = AWS_WEBSERVICE_URL_DEV
.Open "POST", theURL & lambda 'variable that contains generatepresignedurl
.setRequestHeader "Content-type", contentType
.send request
Do: DoEvents: Loop Until .readyState = 4 'make sure we are ready to recieve response
callStandAloneAWSService = .responseText
End With
End Function
上传到PreSigned URL (原始问题没有serversidencryption标头)
Function uploadToPreSignedURL(url As String, whichFile As String, contentType) As Boolean
'code to create binaryFile
Dim httpserver As New MSXML2.XMLHTTP
With httpserver
.Open "POST", url
.setRequestHeader "Content-type", "text/plain" 'contentType
.send binaryFile
Do: DoEvents: Loop Until .readyState = 4 'make sure we are ready to recieve response
If Len(.responseText) = 0 Then
uploadToPreSignedURL = True
Else
'extract error message from xml and write to report mail
End If
End With
End Function
存储桶策略
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::mybiggetybucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::mybiggetybucket/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
FWIW,我可以通过aws cli运行它,并使它工作:
aws s3api put-object --bucket mybiggetybucket --key test.json --body package-lock.json --server-side-encryption“ AES256”
答案 0 :(得分:1)
您不能对使用以下命令上传的对象实施SSE-S3加密 预设网址。您只能使用 AWS管理控制台或HTTP请求标头。欲了解更多 信息,请参阅Specifying Conditions in a Policy。
我能够得到类似的工作。我需要使用PUT而不是POST,并且需要提供x-amz-server-side-encryption:AES256作为标头,如下所示:
const axios = require('axios');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const params = {
Bucket: 'mybucket',
Key: 'myfolder/myfile.txt',
Expires: 60 * 60,
ACL: 'bucket-owner-full-control',
ContentType: 'text/plain',
ServerSideEncryption: 'AES256',
};
const axiosConfig = {
headers: {
'Content-Type': 'text/plain',
'x-amz-server-side-encryption': 'AES256',
},
};
const uploadTextFile = (presignedurl) => {
axios.put(presignedurl, 'some text here', axiosConfig).then((res) => {
console.log('File uploaded');
}).catch((error) => {
console.error(error);
});
};
s3.getSignedUrl('putObject', params, (err, url) => {
if (err) {
console.error(err);
} else {
console.log('Pre-signed URL:', url);
uploadTextFile(url);
}
});