AWS S3优雅地处理403后getSignedUrl过期 [英] AWS S3 gracefully handle 403 after getSignedUrl expired

查看:2036
本文介绍了AWS S3优雅地处理403后getSignedUrl过期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过一个过期的URL访问的S3资源时,正常处理的403。目前,它返回一个AMZ XML错误页面。我已上传403.html资源,以为我会重定向到。

I'm trying to gracefully handle the 403 when visiting an S3 resource via an expired URL. Currently it returns an amz xml error page. I have uploaded a 403.html resource and thought I could redirect to that.

桶资源保存/获取了我的应用程序的资产。然而,阅读文档我设置桶的属性来处理桶作为一个静态的网页页面,并上传了403.html来斗根。除了公众可以访问的资源403.html所有的公共权限将被阻止。在斗性,网站的设置我指出的403.html为错误页面。参观的http://<斗> .S3-网站 - 美东1.amazonaws.com /一些-asset.html 正确地重定向到 HTTP://<斗> .S3-网站 - 美东1.amazonaws.com / 403.html

The bucket resources are assets saved/fetched by my app. Still, reading the docs I set bucket properties to handle the bucket as a static webpage page and uploaded a 403.html to bucket root. All public permissions are blocked, except public GET access to the resource 403.html. In bucket properties, website settings I indicated the 403.html as error page. Visiting http://<bucket>.s3-website-us-east-1.amazonaws.com/some-asset.html redirects correctly to http://<bucket>.s3-website-us-east-1.amazonaws.com/403.html

然而,当我使用AWS-SDK JS /节点,并调用方法 getSignedUrl('的getObject',则params)生成签名的URL,它返回一个不同的主机URL : https://开头&LT;斗&GT; .s3.amazonaws.com / 访问过期资源这种方法不重定向到403.html。我猜测,由于主机地址是不同的,这是它不会自动重定向的原因。

However, when I use aws-sdk js/node and call method getSignedUrl('getObject', params) to generate the signed url, it returns a different host url: https://<bucket>.s3.amazonaws.com/ Visiting expired resources from this method do not get redirected to 403.html. I'm guessing that since the host address is different this is the reason it is not automatically redirecting.

我还设置了静态的网站的路由规则的条件

I have also set up static website routing rules for condition

<Condition>
  <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
  <ReplaceKeyWith>403.html</ReplaceKeyWith>
</Redirect>

不过,这不是重定向签署网址。所以,我在如何妥善处理这些过期URL的损失。任何帮助将大大AP preciated。

Still that's not redirecting the signed urls. So I'm at a loss of how to gracefully handle these expired urls. Any help would be greatly appreciated.

推荐答案

S3桶有2个面向公众的接口,REST和网站。这是两个主机名之间的差,并且看到在行为的差异。

S3 buckets have 2 public-facing interfaces, REST and website. That is the difference between the two hostnames, and the difference in behavior you are seeing.

他们有两个不同的功能集。

They have two different feature sets.

feature          REST Endpoint       Website Endpoint
---------------- ------------------- -------------------
Access control   yes                 no, public content only
Error messages   XML                 HTML
Redirection      no                  yes, bucket, rule, and object-level
Request types    all supported       GET and HEAD only
Root of bucket   lists keys          returns index document
SSL              yes                 no

来源: http://docs.aws.amazon.com/ AmazonS3 /最新的/ dev / WebsiteEndpoints.html

所以,你可以从表中看到,REST端点支持签署的网址,而不是友好的错误,而该网站的端点支持友好的错误,但没有签名的URL。两者不能混用和匹配,所以你想要做的是没有原生支持S3

So, as you can see from the table, the REST endpoint supports signed URLs, but not friendly errors, while the website endpoint supports friendly errors, but not signed URLs. The two can't be mixed and matched, so what you're trying to do isn't natively supported by S3.

我已经围绕这一限制在一个EC2实例和对REST端点水桶传递所有请求桶通过HAProxy的工作。

I have worked around this limitation by passing all requests for the bucket through HAProxy on an EC2 instance and on to the REST endpoint for the bucket.

当返回403错误消息,代理服务器修改使用新的嵌入式Lua中除preTER ,才加入这个&LT;错误&GT; 标记

When a 403 error message is returned, the proxy modifies the response body XML using the new embedded Lua interpreter, adding this before the <Error> tag.

<?xml-stylesheet type="text/xsl" href="/error.xsl"?>\n

文件 /error.xsl 是公开可读,并使用浏览器端XSLT来渲染pretty的错误响应。

The file /error.xsl is publicly readable, and uses browser-side XSLT to render a pretty error response.

代理还注入了几个其他标记成XML,&LT; ProxyTime&GT; &LT; ProxyHTTP code&GT; 在输出使用。生成的XML如下所示:

The proxy also injects a couple of additional tags into the xml, <ProxyTime> and <ProxyHTTPCode> for use in the output. The resulting XML looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/error.xsl"?>
<Error><ProxyTime>2015-10-13T17:36:01Z</ProxyTime><ProxyHTTPCode>403</ProxyHTTPCode><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>9D3E05D20C1BD6AC</RequestId><HostId>WvdkvIRIDMjfa/1Oi3DGVOTR0hABCDEFGHIJKLMNOPQRSTUVWXYZ+B8thZahg7W/I/ExAmPlEAQ=</HostId></Error>

然后我变化向用户示出使用XSL测试的输出,以确定哪些错误状态S3中已抛出:

Then I vary the output shown to the user with XSL tests to determine what error condition S3 has thrown:

<xsl:if test="//Code = 'AccessDenied'">
  <p>It seems we may have provided you with a link to a resource to which you do not have access, or a resource which does not exist, or that our internal security mechanisms were unable to reach consensus on your authorization to view it.</p>
</xsl:if>

和最后的结果是这样的:

And the final result looks like this:

以上是一般的拒绝访问,因为没有凭据提供。下面是一个过期的签名的例子。

The above is a general "Access Denied" because no credentials were supplied. Here's an example of an expired signature.

过期签名的截图

我不包括主机标识的输出,因为它的丑陋和嘈杂,而且,如果我需要它,代理捕获并记录对我来说,我可以交叉引用请求ID。

I don't include the HostId in the output, since it's ugly and noisy, and, if I ever need it, the proxy captured and logged it for me, and I can cross-reference to the request-id.

作为奖励,当然,通过我的代理运行请求意味着提供了桶的内容时,我可以用我自己的域名的的我自己的SSL证书,我有实时访问日志没有延迟。当代理是在同一地区的水桶,对于数据传输的额外的步骤,不收取额外费用,我已经很高兴这个设置。

As a bonus, of course, running the requests through my proxy means I can use my own domain name and my own SSL certificate when serving up bucket content, and I have real-time access logs with no delay. When the proxy is in the same region as the bucket, there is no additional charge for the extra step of data transfer, and I've been very happy with this setup.

这篇关于AWS S3优雅地处理403后getSignedUrl过期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆