S3 REST API HEAD请求上的403禁止错误 [英] 403 forbidden error on S3 REST API HEAD request
问题描述
我正在尝试向S3 REST API发出HEAD Object请求,但是即使我设置了具有S3必要权限的策略,我仍然收到403 Forbidden错误.响应主体为空,因此我认为它不是签名问题.我已经尝试过对该政策进行多次更改,但似乎没有任何效果.我能够正常放置对象和删除对象,只是HEAD不起作用.
Im trying do do a HEAD Object request to the S3 REST API but I keep getting a 403 Forbidden error, even though I have the policy setup with the necessary permissions on S3. The response body is empty, so I don't think its a signature problem. I've tried several changes to the policy, nothing seems to make it work. I'm able to PUT objects and DELETE objects normally, just HEAD doesn't work.
这是我的存储桶策略:
{
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:: 999999999999:user/User"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::999999999999:user/User"
},
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:DeleteObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
有什么想法吗?
更新:
就像迈克尔指出的那样,我的签名似乎有问题,尽管我看不到.
As Michael pointed out it seems to be a problem with my signature, though Im failing to see what.
def generate_url options={}
options[:action] = options[:action].to_s.upcase
options[:expires] ||= Time.now.to_i + 100
file_path = "/" + @bucket_name + "/" + options[:file_name]
string_to_sign = ""
string_to_sign += options[:action]
string_to_sign += "\n\n#{options[:mime_type]}\n"
string_to_sign += options[:expires].to_s
string_to_sign += "\n"
string_to_sign += file_path
signature = CGI::escape(
Base64.strict_encode64(
OpenSSL::HMAC.digest('sha1', SECRET_KEY, string_to_sign)
)
)
url = "https://s3.amazonaws.com"
url += file_path
url += "?AWSAccessKeyId=#{ACCESS_KEY}"
url += "&Expires=#{options[:expires]}"
url += "&Signature=#{signature}"
url
end
生成的要签名的字符串如下所示:
The generated string to sign looks like this:
HEAD\n\n\n1418590715\n/video-thumbnails/1234.jpg"
解决方案:
似乎在开发文件PUT部分时,我实际上已经破坏了GET和HEAD.我正在传递一个空字符串作为请求的主体,而不是不传递任何内容,而是使签名上需要的mime类型并破坏了它,因为我没有提供mime类型.我只是删除了空的请求主体,它运行良好.感谢Michael为我指出的错误方向(我浪费了太多时间更改存储桶策略).
It seems at some point while developing the file PUT part I actually have broken GET and HEAD. I was passing an empty string as the body of the request, instead of passing nothing, making the mime type required on the signature and breaking it because I was providing no mime type. I simply removed the empty request body and it worked perfectly. Thanks Michael for pointing me out of the wrong direction I was(I wasted so much time changing the bucket policy).
推荐答案
它仍然可能是您的签名,由于以下原因,我怀疑是这样的:
It still could be your signature, and I suspect that it is, for the following reasons:
您对消息正文是一个很好的观察结果的观察;但是,这并不意味着您已得出结论.
Your observation that the message body is a good observation; however, it doesn't mean what you have concluded it means.
在这种情况下,缺少响应正文根本不会给您任何有关错误性质的信息,因为无论如何,Web服务器都不应随HEAD
响应一起返回正文:
The lack of a response body does not give you any information at all about the nature of the error, in this case, because a web server is not supposed to return a body along with a HEAD
response, no matter what:
HEAD
方法与GET
相同,除了服务器MUST NOT
在响应中返回消息正文
The
HEAD
method is identical toGET
except that the serverMUST NOT
return a message-body in the response
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (RFC-2616)
— http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (RFC-2616)
从我这一边进行测试,我确认S3对未签名的HEAD
请求和对错误签名的HEAD
请求的响应没有什么不同:它始终是HTTP/1.1 403 Forbidden
,没有消息正文.
Testing this on my side, I've confirmed that S3's response to an unsigned HEAD
request and to an incorrectly-signed HEAD
request is no different: it's always HTTP/1.1 403 Forbidden
with no message body.
还请注意,GET
的签名URL对HEAD
无效,反之亦然.
Note, also, that a signed URL for GET
is not valid for HEAD
, and vice versa.
在S3 签名版本2 和S3 签名版本4 ,即签署"包括"HTTP动词",这将是GET
或HEAD
,这意味着对于GET
有效的签名对于HEAD
无效,反之亦然...在签名时必须知道请求方法,因为它是签名过程中使用的元素.
In both S3 Signature Version 2 and S3 Signature Version 4, the "String to Sign" includes the "HTTP Verb," which would be GET
or HEAD
, meaning that a signature that's valid for GET
would not be valid for HEAD
, and vice versa... the request method must be known at the time of signing, because it's an element that's used in the signing process.
s3:GetObject
权限是唯一的记录的权限使用HEAD
是必需的,如果GET
在工作,这似乎可以消除权限问题,这将指向签名,这是潜在的问题.
The s3:GetObject
permission is the only documented permission required for using HEAD
, which seems to eliminate permissions as the problem, if GET
is working, which points back to the signature as the potential issue.
这篇关于S3 REST API HEAD请求上的403禁止错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!