AWS CloudFrontの署名付きURLでOAI使ってS3にPUTしたファイルにHeadObjectすると Forbidden: null
取り急ぎ パーミッションとかバケットポリシーに問題が無い前提で
S3の前にCloudFrontを立てて、CloudFrontの署名付きURLを使ってS3にPUTしたファイルに HeadObject
すると Forbidden
になるという問題があった。
CloudFrontはOrigin Access Identityを使ってS3にアクセスする設定にしてあった。
Node.jsの aws-sdk
を使ってたんだけど、そのとき出たエラーが↓こう。
Forbidden: null
at (スタックトレース略) {
code: 'Forbidden',
region: null,
time: 2021-04-12T08:59:21.533Z,
requestId: 'TAZDEXMQVVRSNZCS',
extendedRequestId: 'kbvRs/4hcxd5clKBPwQvCKNDxoi6EmBOL3HvzOsjJtr+EnwN5tr34Ykam0cxJCdqKJ7q4tH6PTU=',
cfId: undefined,
statusCode: 403,
retryable: false,
retryDelay: 27.604741445880542
}
同じことをAWS-CLIでやると↓こう。
aws s3api head-object --bucket my-terrible-bucket --key "hogehoge"
An error occurred (403) when calling the HeadObject operation: Forbidden
AWSコンソールからS3上の当該ファイルを確認すると、ファイルの所有者がOAIになっており、これのせいで他の人が触れなくなってしまっているらしい。
似たようなケースは公式に記載があったんだけど……
他のアカウントによってアップロードされた S3 オブジェクトから 403 エラーを解決する
他のアカウントじゃなくて同じアカウントのOrigin Access Identityなのですが
いろいろ調べてドンピシャだったのは以下の記事。
結論だけ書くと、S3にファイルをアップロードする時にACL bucket-owner-full-control
を指定するとエラーにならなくなる。
S3に直接 PutObject
するならAWS-CLIで --acl bucket-owner-full-control
を指定すればいいらしいんだけど、ここではCloudFrontの署名付きURLだからそれは違う。
コマンドラインから curl
とか、Webアプリから axios
とかでPUTする場合は、リクエストヘッダ X-Amz-Acl: bucket-owner-full-control
を付与すればよい。
↓こんなかんじ。
curl -X PUT -H "Content-Type: text/plain" -H "X-Amz-Acl: bucket-owner-full-control" -d @aaaaa.txt "https://xxxxxxxxxxxxxx.cloudfront.net/hogehoge?Expires=1618217168..."
同じことで困ってる人がいたらやってみて