AWS SDK for Java でリクエスト署名バージョンを確認する

2020.08.06

はじめに

SES APIへの署名バージョンを確認する必要があったので使っているSDKでの署名バージョンを確認しました。

先に結論からいうとSDKのバージョン1.8.10以降であればV4署名が使用されています。これはAWS4Signerのコミットログからも確認できます。

AWS SDKの通信ログ

とはいえ自分の目で通信を確認してみたくなるのが人情というものです。AWS SDKが行っている通信ログの出力方法は開発者ガイドに記載があります

場合によっては、AWS SDK for Java によって送受信されたリクエストとレスポンスを詳細に表示すると役立つことがあります。このログ記録は、実稼働システムでは有効にしないでください。これは、リクエストに関する出力 (例: Amazon S3 にアップロードされるファイル) やレスポンスに関する出力のサイズが大きくなり、アプリケーションの速度が非常に遅くなる場合があるためです。この情報にアクセスする必要がある場合は、Apache HttpClient 4 ロガーを使用して、一時的に有効にすることができます。apache.http.wire ロガーの DEBUG レベルを有効にすると、すべてのリクエストデータとレスポンスデータに対するログ記録が有効になります。

※ ロガー名は参照元ページではapache.http.wireとなっていますが正しくはorg.apache.http.wireとなります。

上記のログを有効にして実際にAPIリクエストするプログラムを実行してログを確認してみます。

ロガーの設定

AWS SDK for Java v1 ではcommons loggingを使用しています。ここでは追加のロギングライブラリは使わずcommons logging組み込みのSimpleLogを設定する例を紹介します。

SimpleLogを使う場合、以下の2つのファイルをクラスパス上に作成します。開発者ガイドにある通りロガー org.apache.http.wireのレベルをdebugに設定します。

commons-logging.properties

org.apache.commons.logging.log=org.apache.commons.logging.impl.SimpleLog

simplelog.properties

org.apache.commons.logging.simplelog.defaultlog=info
# ロガーにdebugレベルを設定
org.apache.commons.logging.simplelog.log.org.apache.http.wire=debug
org.apache.commons.logging.simplelog.showdatetime=false
org.apache.commons.logging.simplelog.dateTimeFormat=false

リクエスト送信のサンプルコード

SESへリクエストを行うコードの例は下記のようになります。具体的なパラメータを指定せずともリクエストが送信されるので最低限のコードで大丈夫です。

package example;

import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.SendEmailRequest;

public class Main {
    public static void main(String[] args) {
        new AmazonSimpleEmailServiceClient().sendEmail(new SendEmailRequest());
    }
}

リクエストログ

実際のログは以下のようになります。Authorizationの行を見るとv4署名を使用していることがわかります。

[DEBUG] wire - >> "POST / HTTP/1.1[\r][\n]"
[DEBUG] wire - >> "Host: email.us-east-1.amazonaws.com[\r][\n]"
[DEBUG] wire - >> "Authorization: AWS4-HMAC-SHA256 Credential=XXXXXXXXXX/20200806/us-east-1/email/aws4_request, SignedHeaders=host;user-agent;x-amz-date, Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXXX[\r][\n]"
[DEBUG] wire - >> "X-Amz-Date: 20200806T090605Z[\r][\n]"
[DEBUG] wire - >> "User-Agent: aws-sdk-java/1.8.10 Mac_OS_X/10.15.6 OpenJDK_64-Bit_Server_VM/25.242-b08/1.8.0_242[\r][\n]"
[DEBUG] wire - >> "Content-Type: application/x-www-form-urlencoded; charset=utf-8[\r][\n]"
[DEBUG] wire - >> "Content-Length: 35[\r][\n]"
[DEBUG] wire - >> "Connection: Keep-Alive[\r][\n]"

まとめ

AWS SDK for Javaの通信ログを有効化して使用しているリクエスト署名のバージョンを確認しました。