7

期限切れの URL を介して S3 リソースにアクセスするときに、403 を適切に処理しようとしています。現在、amz xml エラー ページを返します。403.html リソースをアップロードしましたが、そこにリダイレクトできると思いました。

バケット リソースは、アプリによって保存/フェッチされたアセットです。それでも、ドキュメントを読んで、バケットのプロパティを設定してバケットを静的な Web ページとして処理し、403.html をバケット ルートにアップロードしました。リソース 403.html へのパブリック GET アクセスを除き、すべてのパブリック アクセス許可がブロックされます。バケットのプロパティ、ウェブサイトの設定で、403.html をエラー ページとして示しました。訪問http://<bucket>.s3-website-us-east-1.amazonaws.com/some-asset.htmlすると正しくリダイレ​​クトされますhttp://<bucket>.s3-website-us-east-1.amazonaws.com/403.html

ただし、aws-sdk js/node を使用してメソッドを呼び出しgetSignedUrl('getObject', params)て署名付き URL を生成すると、別のホスト URL が返されますhttps://<bucket>.s3.amazonaws.com/。このメソッドから期限切れのリソースにアクセスすると、403.html にリダイレクトされません。ホストアドレスが異なるため、これが自動的にリダイレクトされない理由だと思います。

条件の静的 Web サイト ルーティング ルールも設定しました

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

それでも、署名付き URL をリダイレクトしていません。したがって、これらの期限切れの URL を適切に処理する方法がわかりません。どんな助けでも大歓迎です。

4

1 に答える 1

12

S3 バケットには、REST と Web サイトの 2 つのパブリック インターフェイスがあります。これが 2 つのホスト名の違いであり、表示されている動作の違いです。

これらには 2 つの異なる機能セットがあります。

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/latest/dev/WebsiteEndpoints.html

したがって、表からわかるように、REST エンドポイントは署名付き URL をサポートしますが、わかりやすいエラーはサポートしません。一方、Web サイト エンドポイントはわかりやすいエラーをサポートしますが、署名付き URL はサポートしません。2 つを混在させて一致させることはできないため、あなたがしようとしていることは S3 でネイティブにサポートされていません。


EC2 インスタンスの HAProxy を介してバケットのすべてのリクエストを渡し、バケットの REST エンドポイントに渡すことで、この制限を回避しました。

403 エラー メッセージが返されると、プロキシは新しい埋め込み Lua インタープリター<Error>を使用して応答本文の XML を変更し、これをタグの前に追加します。

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

このファイル/error.xslは公開されており、ブラウザー側の XSLT を使用してかなりのエラー応答をレンダリングします。

また、プロキシは、いくつかの追加タグを xml に挿入し、出力<ProxyTime><ProxyHTTPCode>使用します。結果の XML は次のようになります。

<?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 がスローしたエラー条件を特定します。

<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>

最終結果は次のようになります。

この動作のブラウザ スクリーンショットの例

上記は、資格情報が提供されていないため、一般的な「アクセスが拒否されました」です。期限切れの署名の例を次に示します。

期限切れの署名のスクリーンショット

醜くてうるさいので、出力には含めません。HostId必要に応じて、プロキシがキャプチャしてログに記録し、request-id を相互参照できます。

もちろんおまけとして、プロキシ経由でリクエストを実行すると、バケット コンテンツを提供するときに独自のドメイン名独自の SSL 証明書を使用できることになり、リアルタイムのアクセス ログを遅滞なく取得できます。プロキシがバケットと同じリージョンにある場合、データ転送の追加ステップに対する追加料金は発生せず、このセットアップに非常に満足しています.

于 2015-10-13T18:04:59.733 に答える