【AWS】presigned URLsを使おうとしたらSignatureDoesNotMatchが出たときの対処

【AWS】presigned URLsを使おうとしたらSignatureDoesNotMatchが出たときの対処


AWSのファイルストレージであるS3(Simple Storage Service)には一時的にユーザーにアップロードやファイル閲覧が出来るようになる、presigned URLs(署名付きURL)を発行する機能が存在します。

このpresigned URLsの発行にあたっては、色々な先駆者の方々が記事を書いてくださっていますが、この発行されたpresigned URLsを使う側の記事は殆ど見当たらずに詰まってしましいました。

SignatureDoesNotMatchというエラー

「SignatureDoesNotMatch」というエラーが出ました。返却されたURLそのまま使ったのに署名が適切じゃないとかどういうことやねん。 ということで四苦八苦していました。

いくつか失敗するパターンが有るようなので、列挙しておこうと思います。 にしても親切じゃないエラーです…

エラーが起きる原因と対処方法

署名のバージョンが不適切

署名のバージョンがv4 でないと上手く動かないことがあるようです。 こちらはURLを発行する際に指定をするものとなりますので、発行するプログラムを担当している人に確認しましょう。

こんな感じで指定を行います。

# https://boto3.amazonaws.com/v1/documentation/api/1.9.42/guide/s3.html#generating-presigned-urls

import boto3
from botocore.client import Config

# Get the service client with sigv4 configured
s3 = boto3.client('s3', config=Config(signature_version='s3v4'))

# Generate the URL to get 'key-name' from 'bucket-name'
url = s3.generate_presigned_url(
    ClientMethod='get_object',
    Params={
        'Bucket': 'bucket-name',
        'Key': 'key-name'
    }
)

 

https://github.com/aws/aws-sdk-js/issues/902

なお、署名のバージョンを2020年6月時点では、v4はデフォルトではないようです。

なお、こちらの記事によるとダウンロード(GET)用のURLではエラーが出ず、アップロード(PUT)用URLではエラーが出るとのことです。なんだそれ…

有効期限の設定がよりも先に期限切れになってしまっている

AWSが公式に記事を出してくれていますが、有効期限を待たずにURLが失効されてしまうことがあります。

  • AWS Identity and Access Management (IAM) インスタンスプロファイル: 最大 6 時間有効
  • AWS Security Token Service (STS): 最大 36 時間有効 (AWS アカウントユーザーや IAM ユーザーの認証情報など、永続的認証情報を使用して署名した場合)
  • IAM ユーザー: 最大 7 日間有効 (AWS 署名バージョン 4 を使用した場合)

詳細は以下の記事をご参照下さい。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/presigned-url-s3-bucket-expiration/

ヘッダにContent-Typeの指定がない

私が今回苦しんだのはこれでした。

Pythonのrequestsモジュールを使用してputしていたのですが、明示的にcontent-typeを指定していないことが原因でした。 これでエラーがSignatureDoesNotMatchなので、中々たどり着けませんでした…。

なので、以下のような形でヘッダにContent-Typeを指定してあげることで解決しました。

with open(csv_path, mode='rb') as f:
    res_put = requests.put(
        url=preSignedUrl,
        data=f,
        headers={'Content-Type': 'text/csv'}
    )

 

ここらへんまとまったドキュメント見つからなかったのですが、どこかにあるのでしょうか…。 もしあるのであればぜひ教えて頂きたいです。。