当前位置: 首页 > 知识库问答 >
问题:

更正预签名URL的S3策略

萧树
2023-03-14

我需要发布预签名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/*"
            ]
        }
    ]
}

共有3个答案

邵子平
2023-03-14

Bucket权限与对象权限

您的策略的以下权限应位于Bucket级别(arn: aws: s3::: MyBucket),而不是Bucket中的子路径(例如arn: aws: s3::: MyBucket/*):

  • s3:CreateBucket

请参阅:在策略中指定权限

但是,这不是您无法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
毛弘博
2023-03-14

我还开发了一个使用预签名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"
    }
  ]
}
贺子昂
2023-03-14

这是一个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时,我会得到以下信息:, 我尝试使用命令