问题
When I try to upload a picture to a "Car" object I'm denied access to S3. But the site images that are in the assets folder have displayed just fine since I added S3. The specific error that I get is this:
2015-02-17T14:40:48.459629+00:00 app[web.1]: Excon::Errors::Forbidden (Expected(200) <=> Actual(403 Forbidden)
2015-02-17T14:40:48.459630+00:00 app[web.1]: excon.error.response
2015-02-17T14:40:48.459635+00:00 app[web.1]: "Connection" => "close"
2015-02-17T14:40:48.459637+00:00 app[web.1]: "Content-Type" => "application/xml"
2015-02-17T14:40:48.459639+00:00 app[web.1]: "Date" => "Tue, 17 Feb 2015 14:40:48 GMT"
2015-02-17T14:40:48.459640+00:00 app[web.1]: "Server" => "AmazonS3"
2015-02-17T14:40:48.459632+00:00 app[web.1]: :body => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>2CE306ACD51F02A1</RequestId><HostId>tKLXUAKxyDFTMExl7kE+AuVVsEJOFqXh983li6N7R2UlYDXv1Z3GJRvW5zy1XIXVs2zArp310vg=</HostId></Error>"
2015-02-17T14:40:48.459642+00:00 app[web.1]: "x-amz-id-2" => ""part of secret key"="
With "part of secret key" obviously redacted. I've tried creating a different user and using new keys, but that hasn't worked. Not where to go from here.
app/uploaders/picture_uploader
class PictureUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
process resize_to_limit: [400, 400]
if Rails.env.production?
storage :fog
else
storage :file
end
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# Add a white list of extensions which are allowed to be uploaded.
def extension_white_list
%w(jpg jpeg gif png)
end
end
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']
}
config.fog_directory = ENV['S3_BUCKET']
end
end
I believe that's all of the relevant files, let me know if there's more to see. Not sure if specifying a region or a power user would help, doesn't seem like it would.
回答1:
[EDIT: I'd default to the other answer at this point, especially if you're in a prod environment. This was a workaround that worked for me while building a breakable toy a few years back, but I agree with granting minimal permissions when security is a concern.]
I was encountering the same error, and the solution was to attach administrative access policies from the AWS Management Console:
1) Sign in to the AWS Management Console at http://aws.amazon.com/iam/
2) Click "Policies" from the Navigation Pane on the left
3) Select the "AdministratorAccess" policy
4) Click Policy Actions > Attach at the top of the page
5) Select the user associated with my S3_ACCESS_KEY, S3_SECRET_KEY, and S3_BUCKET
6) Click "Attach Policy"
Merely granting all permissions from my bucket at https://console.aws.amazon.com/s3/home was not sufficient.
回答2:
The other answer telling you to grant AdministratorAccess on the IAM user is a bad idea from a security point of view - it will allow anyone with access to those keys to perform any action in your account, including deleting all infrastructure.
I haven't worked out the exact minimum set of permissions that Carrierwave / Fog needs, but a smaller set that I got working looks like:
Create an AWS IAM Policy with a policy document like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::BUCKETNAME/*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::BUCKETNAME"
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
]
}
]
}
Note, that it is not an error to specify S3 actions on both BUCKETNAME
and BUCKETNAME/*
- the first relates to API actions that are performed on the bucket, and the second, on stored objects within the bucket.
回答3:
I used this manual: https://medium.com/@mohit_22386/ruby-on-rails-aws-how-to-put-assets-on-aws-s3-and-fetch-using-cloudfront-84de9800ce3d
After setup I could add or remove files from bucket via software (DragonDisk). But i got the same error on assets:precompile. I just removed ACL's ckeckboxes on the Permissions > Public access settings page in bucket settings:
Also, I've used my main account, no IAM, so Rob Mulholand's aswer wasn't relevant for me.
回答4:
A more minimal permission approach would be this one:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "<IAM user with programatic access>"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::BUCKETNAME"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "<IAM user with programatic access>"
},
"Action": [
"s3:PutObjectAcl",
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::BUCKETNAME/*"
}
]
}
tl;dr: You also need the s3:PutObjectAcl permission.
(I did not check if it would even work without GetObject, DeleteObject permission because in my case I wanted to grant them anyway.)
回答5:
Make sure config.fog_public = false
in carrierwave.rb
if your bucket is not public.
来源:https://stackoverflow.com/questions/28564653/exconerrorsforbidden-expected200-actual403-forbidden