简体   繁体   English

AWS S3访问策略-Web浏览器与API

[英]AWS S3 Access Policy - web browser vs API

UPDATE: I eventually answered my own question. 更新:我最终回答了自己的问题。 See the Answers section for a tutorial that solves this problem. 有关解决此问题的教程,请参见“答案”部分。

The question: What exactly is the policy that is needed for an external source to access an AWS S3 bucket through the API controls? 问题:外部源通过API控件访问AWS S3存储桶到底需要什么策略?

Details: I'm following the Rails Tutorial by Michael Hartl, and I reached the end of lesson 11 where we use CarrierWave to store image files in an AWS S3 bucket. 详细信息:我正在遵循Michael Hartl的Rails教程,并且在第11课结束时,我们使用CarrierWave将图像文件存储在AWS S3存储桶中。 I was able to get it to work (had to add a region ENV variable) but only with a user who has full admin privileges. 我能够使它正常工作(必须添加区域ENV变量),但只有具有完全管理员权限的用户才能使用。 Obviously that's not ideal. 显然,这并不理想。 I created a User account specifically for the purpose, but all the walkthroughs only seem to be concerned with web browser access. 我专门为此目的创建了一个用户帐户,但是所有演练似乎只与Web浏览器访问有关。 In fact, I was able to create policies that would allow the user to only be able to read, write, and delete in the specific bucket, but that only worked through a web browser and not through the API. 实际上,我能够创建允许用户只能在特定存储桶中进行读取,写入和删除的策略,但是只能通过Web浏览器而不是通过API进行操作。 The API access only worked when I attached the AdministratorAccess policy. 仅当我附加了AdministratorAccess策略时,API访问才起作用。

Here's what I have so far: 这是我到目前为止的内容:

Policy: AllowRootLevelListingOfMyBucket 策略:AllowRootLevelListingOfMyBucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGroupToSeeBucketListAndAlsoAllowGetBucketLocationRequiredForListBucket",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::*"
            ]
        },
        {
            "Sid": "AllowRootLevelListingOfMyBucket",
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::MyBucket"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:prefix": [
                        ""
                    ],
                    "s3:delimiter": [
                        "/"
                    ]
                }
            }
        }
    ]
}

Policy: AllowUserToReadWriteObjectDataInMyBucket 策略:AllowUserToReadWriteObjectDataInMyBucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToReadWriteObjectDataInMyBucket",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::MyBucket/*"
            ]
        }
    ]
}

As I said, this allows web browser access, but API access attempts return an "AccessDenied" error: Excon::Errors::Forbidden (Expected(200) <=> Actual(403 Forbidden) 就像我说的,这允许Web浏览器访问,但是API访问尝试会返回“ AccessDenied”错误:Excon :: Errors :: Forbidden(Expected(200)<=> Actual(403 Forbidden)

What do I need to add for API access? 我需要为API访问添加什么?

Update: I have narrowed down the problem a bit. 更新:我已将问题缩小了一点。 There is some "Action" that I need to give permission for, but I haven't been able to identify the action exactly. 我需要允许某些“操作”,但我无法准确识别该操作。 But using a wildcard works, and I've been able to lock down the user account to only be able to access one bucket. 但是使用通配符是可行的,而且我已经能够锁定用户帐户,使其只能访问一个存储桶。 Here's the change I made: 这是我所做的更改:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowUserToReadWriteObjectDataInMyBucket",
            "Action": [
                "s3:*"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::MyBucket/*"
            ]
        }
    ]
}

I eventually answered my own question, and created a tutorial that others might want to follow: 我最终回答了自己的问题,并创建了一个其他人可能希望遵循的教程:

The first thing you need to do is go back over the code that Hartl provided. 您需要做的第一件事是回顾Hartl提供的代码。 Make sure you typed it (or copy/pasted it) in exactly as shown. 确保完全按照显示的方式键入(或复制/粘贴)。 Out of all the code in this section, there is only one small addition you might need to make. 在本节的所有代码中,您可能只需要添加一小部分。 The "region" environment variable. “区域”环境变量。 This is needed if you create a bucket that is not in the default US area. 如果您创建的存储桶不在默认的美国区域,则需要这样做。 More on this later. 稍后对此进行更多讨论。 Here is the code for /config/initializers/carrier_wave.rb : 这是/config/initializers/carrier_wave.rb的代码:

if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      # Configuration for Amazon S3
      :provider              => 'AWS',
      :aws_access_key_id     => ENV['S3_ACCESS_KEY'],
      :aws_secret_access_key => ENV['S3_SECRET_KEY'],
      :region                => ENV['S3_REGION']
    }
    config.fog_directory     =  ENV['S3_BUCKET']
  end
end

That line :region => ENV['S3_REGION'] is a problem for a lot of people. 那一行:region => ENV['S3_REGION']对于很多人来说都是一个问题。 As you continue this tutorial you will learn what it's for. 在继续本教程时,您将了解它的用途。

You should be using that block of code exactly as shown. 您应该完全按照所示使用该代码块。 Do NOT put your actual keys in there. 不要将您的实际钥匙放在那儿。 We'll send them to Heroku separately. 我们将它们分别发送给Heroku。

Now let's move on to your AWS account and security. 现在,让我们继续您的AWS账户和安全性。

  1. First of all, create your AWS account. 首先, 创建您的AWS账户。 For the most part, it is like signing up for any web site. 在大多数情况下,这就像注册任何网站一样。 Make a nice long password and store it someplace secure, like an encrypted password manager. 制作一个不错的长密码并将其存储在安全的地方,例如加密的密码管理器。 When you make your account, you will be given your first set of AWS keys. 创建帐户时,将为您提供第一套AWS密钥。 You will not be using those in this tutorial, but you might need them at some point in the future so save those somewhere safe as well. 您将不会在本教程中使用它们,但将来可能会需要它们,因此也请妥善保存。
  2. Go to the S3 section and make a bucket. 转到S3部分并创建一个存储桶。 It has to have a unique name, so I usually just put the date on the end and that does it. 它必须有一个唯一的名称,因此我通常只是将日期放在结尾,然后执行此操作。 For example, you might name it "my-sample-app-bucket-20160126". 例如,您可以将其命名为“ my-sample-app-bucket-20160126”。 Once you have created your bucket, click on the name, then click on Properties. 创建存储桶后,单击名称,然后单击“属性”。 It's important for you to know what "Region" your bucket is in. Find it, and make a note of it. 重要的是要知道您的存储桶所在的“区域”。找到并记下它。 You'll use it later. 以后再使用。
  3. Your main account probably has full permissions to everything, so let's not use that for transmitting random data between two web services. 您的主帐户可能具有对所有内容的完全许可权,因此,请勿将其用于在两个Web服务之间传输随机数据。 This could cost you a lot of money if it got out. 如果解决了,这可能会花费您很多钱。 We'll make a limited user instead. 我们将改为限制用户。 Make a new User in the IAM section. 在IAM部分中创建一个新用户。 I named it "fog", because that's the cloud service software that handles the sending and receiving. 我将其命名为“雾”,因为那是处理发送和接收的云服务软件。 When you create it, you will have the option of displaying and/or downoading the keys associated with the new user. 创建它时,您可以选择显示和/或取消与新用户关联的键。 It's important you keep this in a safe and secure place. 请务必将其保存在安全的地方。 It does NOT go into your code, because that will probably end up in a repository where other people can see it. 它不会放入您的代码中,因为它可能最终会存储在其他人可以看到它的存储库中。 Also, don't give this new user a password, since it will not be logging into the AWS dashboard. 另外,请勿为该新用户提供密码,因为它将不会登录到AWS仪表板。
  4. Make a new Group. 新建一个组。 I called mine "s3railsbucket". 我称我为“ s3railsbucket”。 This is where the permissions will be assigned. 这是分配权限的地方。 Add "fog" to this group. 将“雾”添加到该组。
  5. Go to the Policies section. 转到政策部分。 Click "Create Policy" then select "Create Your Own Policy". 单击“创建策略”,然后选择“创建自己的策略”。 Give it a name that starts with "Allow" so it will show up near the top of the list of policies. 给它一个以“允许”开头的名称,这样它将显示在策略列表的顶部附近。 It's a huge list. 这是一个巨大的清单。 Here's what I did: 这是我所做的:

Policy Name: AllowFullAccessToMySampleAppBucket20160126 策略名称: AllowFullAccessToMySampleAppBucket20160126
Description: Allows remote write/delete access to S3 bucket named my-sample-app-bucket-20160126. 说明:允许对名为my-sample-app-bucket-20160126的S3存储桶进行远程写入/删除访问。
Policy Document: 政策文件:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "s3:*",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-sample-app-bucket-20160126",
                "arn:aws:s3:::my-sample-app-bucket-20160126/*"
            ]
        }
    ]
}
  1. Go back to the Group section, select the group you made, then add your new policy to the group. 返回“组”部分,选择您创建的组,然后将新策略添加到该组。

That's it for AWS configuration. AWS配置就是这样。 I didn't need to make a policy to allow "fog" to list the contents of the bucket, even though most tutorials I tried said that was necessary. 即使我尝试过的大多数教程都说有必要,我也不需要制定政策允许“雾”列出存储桶的内容。 I think it's only necessary when you want a user that can log in through the dashboard. 我认为只有在希望用户可以通过仪表板登录时才需要这样做。

Now for the Heroku configuration. 现在进行Heroku配置。 This stuff gets entered in at your command prompt, just like 'heroku run rake db:migrate' and such. 这些东西会在您的命令提示符下输入,就像“ heroku run rake db:migrate”之类。 This is where you enter the actual Access Key and Secret Key you got from the "fog" user you created earlier. 在这里,您可以输入从先前创建的“雾”用户那里获得的实际访问密钥和秘密密钥。

$ heroku config:set S3_ACCESS_KEY=THERANDOMKEYYOUGOT  
$ heroku config:set S3_SECRET_KEY=an0tHeRstRing0frAnDomjUnK  
$ heroku config:set S3_REGION=us-west-2  
$ heroku config:set S3_BUCKET=my-sample-app-bucket-20160126

Look again at that last one. 再看最后一个。 Remember when you looked at the Properties of your S3 bucket? 还记得当您查看S3存储桶的属性吗? This is where you enter the code associated with your region. 在此处输入与您的区域关联的代码。 If your bucket is not in Oregon, you will have to change us-west-2 to your actual region code. 如果您的存储桶不在俄勒冈州,则必须将us-west-2更改为您的实际区域代码。 This link worked when this tutorial was written: 在编写本教程时,此链接有效:

http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

If that doesn't work, Google "AWS S3 region codes". 如果这不起作用,请使用Google“ AWS S3地区代码”。

After doing all this and double-checking for mistakes in the code, I got Heroku to work with AWS for storage of pictures! 完成所有这些操作并仔细检查代码中的错误之后,我让Heroku与AWS一起使用来存储图片!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM