我需要发布预签名URL,允许用户获取文件并将其放入特定的S3存储桶。我创建了一个IAM用户,并使用其密钥创建预签名URL,并在该用户中添加了一个嵌入的自定义策略(见下文)。当我使用生成的URL时,我的策略出现了一个AccessDenied错误。如果我向IAM用户添加FullS3Access策略,则可以使用相同的URL获取或放置文件,因此显然缺少我的自定义策略。它怎么了?
以下是我正在使用的不起作用的自定义策略:
{
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::MyBucket"
]
},
{
"Action": [
"s3:AbortMultipartUpload",
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteBucketPolicy",
"s3:DeleteObject",
"s3:GetBucketPolicy",
"s3:GetLifecycleConfiguration",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts",
"s3:PutBucketPolicy",
"s3:PutLifecycleConfiguration",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::MyBucket/*"
]
}
]
}
Bucket权限与对象权限
您的策略的以下权限应位于Bucket级别(arn: aws: s3::: MyBucket
),而不是Bucket中的子路径(例如arn: aws: s3::: MyBucket/*
):
请参阅:在策略中指定权限
但是,这不是您无法PUT或GET文件的原因。
获取
您已分配GetObject权限这一事实意味着您应该能够从S3存储桶中获取对象。我通过将您的策略分配给用户进行了测试,然后使用该用户的凭据访问对象,并且它可以正常工作。
放置
我还使用了你的策略通过网络表单上传,它工作正常。
这是我用来上传的表格:
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>S3 POST Form</title>
<style type="text/css"></style></head>
<body>
<form action="https://<BUCKET-NAME>.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="uploads/${filename}">
<input type="hidden" name="AWSAccessKeyId" value="<ACCESS-KEY>">
<input type="hidden" name="acl" value="private">
<input type="hidden" name="success_action_redirect" value="http://<BUCKET-NAME>.s3.amazonaws.com/ok.html">
<input type="hidden" name="policy" value="<ENCODED-POLICY>">
<input type="hidden" name="signature" value="<SIGNATURE>">
<input type="hidden" name="Content-Type" value="image/jpeg">
<!-- Include any additional input fields here -->
File to upload to S3:
<input name="file" type="file">
<br>
<input type="submit" value="Upload File to S3">
</form>
下面是我如何生成签名的:
#!/usr/bin/python
import base64
import hmac, hashlib
policy_document = '{"expiration": "2018-01-01T00:00:00Z", "conditions": [ {"bucket": "<BUCKET-NAME>"}, ["starts-with", "$key", "uploads/"], {"acl": "private"}, {"success_action_redirect": "http://BUCKET-NAME.s3.amazonaws.com/ok.html"}, ["starts-with", "$Content-Type", ""], ["content-length-range", 0, 1048000] ] }'
AWS_SECRET_ACCESS_KEY = "<SECRET-KEY>"
policy = base64.b64encode(policy_document)
signature = base64.b64encode(hmac.new(AWS_SECRET_ACCESS_KEY, policy, hashlib.sha1).digest())
print policy
print
print signature
我还开发了一个使用预签名GET和put URL的功能,特别是通过与AWS Lambda函数关联的角色。不过我发现了一个转折点,我还需要允许使用加密存储桶的KMS密钥。
我偶然发现了这篇不为人知的文章,这篇文章为我指明了正确的方向。URL预签名不需要允许bucket级权限,只需要少数对象级权限。
简而言之,我支持预签名URL的lambda角色策略如下所示。请注意,cloudwatch日志权限与签名无关,但通常对lambda函数很重要:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "<my-bucket-arn-expression>/*",
"Effect": "Allow"
},
{
"Sid": "KMSAccess",
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:GenerateDataKey*",
"kms:ReEncrypt*"
],
"Effect": "Allow",
"Resource": "<my-key-arn>"
}
]
}
如果您使用的是内置AES加密(或不加密),您的策略可以简化为:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*",
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "<my-bucket-arn-expression>/*",
"Effect": "Allow"
}
]
}
这是一个IAM策略,适用于我预先指定的S3 URL。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mydocs/*"
}
]
}
我想知道您的问题是否在资源
部分。您对桶MyBucket
的GET请求总是吗?
标题说明一切。这是我的代码; 我使用节点强大的文件。 成功上传后,url变量返回s3 url,类似以下内容; 下面是我的参数 我错过了什么?
我试图使用S3预签名的PUT url执行文档上传。我使用java AWSSDK(GeneratePresignedUrlRequest.java)生成url。此url生成代码位于AWS API网关后面的lambda函数中。 然而,当我在Postman中复制生成的url时,我遇到了以下错误 生成的url是“https:// 关于在生成url时需要更正的内容,有什么建议吗?
我知道水桶是存在的。当我通过AWS Web GUI导航到此项目并双击它时,它将打开带有URL的对象,并且运行良好: 所以我认为我在使用SDK时肯定做错了什么。
我尝试将Content-Type的头修改为multipart/form-data和application/octet-stream。我还尝试取消postman中的headers部分,并在选择文件时依赖于表单数据和二进制设置的正文类型。“表单-数据”设置会将以下内容添加到调用中: 内容-处置:表单-数据;name=“TheFileTosend.txt”;filename=“TheFileTosend
我试图上传图像/视频使用PHP/Javascript到AWS S3 这是我的PHP代码 这是我的Java脚本代码 所有这些功能工作伟大,我想即使在执行它给我文件上传成功消息too.but当我检查s3什么都没有。 即使在控制台中,它也会像下面一样生成预签名URL。但当我尝试单击它时,它会给我SignatureDesNotMatch错误。(请单击URL)。可能是什么错误。。? https://ibra
我有下面的lambda,它在将文件上传到bucket并将其预签名的URL发送到API时被触发。 这是生成预先签名的URL,但我无法使用它访问文件。当我在浏览器中键入URL时,我会得到以下信息:, 我尝试使用命令