すべてのプロダクト
Search
ドキュメントセンター

API Gateway:hmac-auth

最終更新日:Sep 10, 2026

hmac-auth プラグインは、HMAC アルゴリズムに基づいて HTTP リクエストの改ざんできない署名を生成し、その署名を ID 認証に使用します。

プラグインタイプ

認証と認可。

フィールド

認証設定

フィールド

データ型

必須

デフォルト値

説明

consumers

オブジェクトの配列

はい

-

サービスの呼び出し元です。リクエストの認証に使用します。

date_offset

number

いいえ

-

許容されるクライアント時刻オフセットの最大値です (秒)。システムは、リプレイ攻撃を防ぐために、Date リクエストヘッダーからクライアントの UTC 時刻を解析します。設定しない場合、システムはクライアントの UTC 時刻を検証しません。

global_auth

boolean

いいえ (インスタンスレベルでの設定の場合にのみ必須)

-

インスタンスレベルのみ。true に設定すると、認証がグローバルに有効になります。false に設定すると、認証が設定済みのドメイン名とルートにのみ適用されます。未設定の場合、ドメイン名またはルートが設定されていないときに限り、認証がグローバルに有効になります。

consumers のフィールド:

フィールド

データ型

必須

デフォルト値

説明

key

string

はい

-

コンシューマーのアクセスキーです。

secret

string

はい

-

署名の生成に使用するシークレットです。

name

string

はい

-

コンシューマーの名前です。

(オプション) 認可設定

フィールド

データ型

必須

デフォルト値

説明

allow

文字列の配列

いいえ (インスタンスレベル以外の設定の場合に必須)

-

ルートまたはドメイン名レベルでのみ設定できます。きめ細かい権限制御のために、一致したリクエストへのアクセスを許可するコンシューマーを指定します。

重要
  • 同一ルール内で、認可設定と認証設定を併用することはできません。

  • 認証済みリクエストの場合、呼び出し元を識別するために X-Mse-Consumer ヘッダーが追加されます。

例

認証のグローバル設定とルートの認可設定

次の例では、特定のルートまたはドメインに対して hmac-auth 認証を有効にします。key フィールドは一意である必要があります。

次のプラグイン設定をインスタンスレベルで適用します:

global_auth: false
consumers: 
- key: appKey-example-1
  secret: appSecret-example-1
  name: consumer-1
- key: appKey-example-2
  secret: appSecret-example-2
  name: consumer-2

次のプラグイン設定を route-a および route-b ルートに適用します:

allow:
- consumer-1

次のプラグイン設定を *.example.com および test.com ドメイン名に適用します:

allow:
- consumer-2
説明
  • この例の route-a および route-b ルートは、ゲートウェイルートの作成時に指定したルートです。クライアントリクエストがいずれかのルートに一致した場合、name が consumer-1 の呼び出し元がゲートウェイにアクセスできます。それ以外の呼び出し元はゲートウェイにアクセスできません。

  • この例の *.example.com および test.com ドメイン名は、リクエスト内のドメイン名の照合に使用します。クライアントリクエストがいずれかのドメイン名に一致した場合、name が consumer-2 の呼び出し元がゲートウェイにアクセスできます。それ以外の呼び出し元はゲートウェイにアクセスできません。

グローバル認証の設定

global_auth: true
consumers: 
- key: appKey-example-1
  secret: appSecret-example-1
  name: consumer-1
- key: appKey-example-2
  secret: appSecret-example-2
  name: consumer-2

署名メカニズム

設定の準備

署名の生成と検証のために、次の認証情報を設定します:

  • key:リクエストヘッダー x-ca-key で使用します。

  • secret:リクエスト署名の生成に使用します。

クライアントでの署名生成

プロセス

クライアントは、次の手順で署名を生成します:

  1. 元のリクエストからキーとなるデータを抽出して、署名文字列を生成します。

  2. 設定した secret で署名文字列を暗号化し、署名を生成します。

  3. 署名に関連するすべてのヘッダーを、元の HTTP リクエストに追加します。

署名文字列の抽出

クライアントは HTTP リクエストからキーとなるデータを抽出し、次の形式で署名文字列に結合します:

HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters

これらのフィールドは \n で区切ります。Headers フィールドが空の場合は \n は不要です。それ以外の空のフィールドについては、\n を保持する必要があります。署名は大文字と小文字を区別します。

各フィールドの抽出ルール:

  • HTTPMethod:POST などの HTTP メソッドです。大文字である必要があります。

  • Accept:Accept リクエストヘッダーの値です。空にできます。一部の HTTP クライアントはデフォルトで */* を設定し、署名検証の失敗原因となるため、Accept ヘッダーを明示的に設定することを推奨します。

  • Content-MD5:Content-MD5 ヘッダーの値です。空にできます。リクエストにフォーム以外のボディが含まれる場合にのみ計算されます。Java の例は次のとおりです:

    String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getBytes("UTF-8")));
  • Content-Type:Content-Type ヘッダーの値です。空にできます。

  • Date:時刻オフセット検証に使用する Date ヘッダーの値です。date_offset が設定されていない場合は空にできます。

  • Headers:署名に含めるヘッダーです。連結ルール:

    • ヘッダーキーをアルファベット順に並べ替え、次のように連結します:

      HeaderKey1 + ":" + HeaderValue1 + "\n" +
      HeaderKey2 + ":" + HeaderValue2 + "\n" +
      ...
      HeaderKeyN + ":" + HeaderValueN + "\n"
    • ヘッダー値が空の場合は、署名に HeaderKey + ":" + "\n" を使用します。キーとコロン (:) は保持する必要があります。

    • 署名に使用するヘッダーキーはカンマ (,) で区切り、X-Ca-Signature-Headers ヘッダーに配置します。

    • 次のヘッダーは署名計算に使用できません:X-Ca-Signature、X-Ca-Signature-Headers、Accept、Content-MD5、Content-Type、Date。

  • PathAndParameters:パス、クエリ、およびフォームパラメーターを含みます。

    Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
説明
  • クエリおよびフォームパラメーターのキーはアルファベット順に並べ替えたうえで、上記のとおりに連結します。

  • クエリおよびフォームパラメーターが空の場合は、署名情報を追加せずにパスのみを使用します。

  • 同じキーで値が異なる配列パラメーターの場合、署名計算には最初の値のみが使用されます。

署名文字列抽出の例

初期 HTTP リクエスト:

POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=taro&password=123456789

生成された署名文字列:

POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
x-ca-key:203753385
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-signature-method:HmacSHA256
x-ca-timestamp:1525872629832
/http2test/test?param1=test&password=123456789&username=taro

署名の計算

署名文字列を生成した後、クライアントはそれを暗号化してエンコードし、最終的な署名を生成します。

このコードでは、stringToSign が抽出した署名文字列、secret がプラグイン設定のシークレット、sign が最終的な署名です。

Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);

stringToSign は UTF-8 バイト配列にエンコードされ、HMAC アルゴリズムで暗号化された後、Base64 エンコードされて署名が生成されます。

署名の追加

署名検証のために、Cloud-native API Gateway に送信するリクエストには次のヘッダーを含めます:

  • x-ca-key:設定した key です。必須です。

  • x-ca-signature-method:署名アルゴリズムです。オプションです。有効な値:HmacSHA256 および HmacSHA1。デフォルト値:HmacSHA256。

  • x-ca-signature-headers:署名ヘッダーキーの一覧です。カンマ (,) で区切ります。オプションです。

  • x-ca-signature:署名です。必須です。

署名付き HTTP リクエストの例:

POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
content-length:33
username=taro&password=123456789

サーバー側での署名検証

プロセス

サーバーは、次の手順でクライアント署名を検証します:

  1. リクエストからキーとなるデータを抽出して、署名文字列を取得します。

  2. リクエストから key を読み取り、対応する secret を検索します。

  3. secret で署名文字列を暗号化し、署名を生成します。

  4. サーバー側の署名と、リクエスト内のクライアント側署名を比較します。

署名エラーのトラブルシューティング

署名検証に失敗した場合、サーバーはサーバー側の StringToSign を X-Ca-Error-Message レスポンスヘッダーで返します。クライアント側の StringToSign と比較して差分を特定してください。

2 つの値が一致する場合は、署名計算に使用した secret を確認してください。

HTTP ヘッダーは改行をサポートしないため、StringToSign 内の改行は # に置き換えられます。

X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`

エラーコード

HTTP ステータスコード

エラーメッセージ

理由

400

Invalid Signature.

x-ca-signature の署名が、サーバーで計算された署名と一致しません。

400

Invalid Content-MD5.

Content-MD5 リクエストヘッダーが無効です。

400

Invalid Date.

Date リクエストヘッダーの時刻オフセットが、設定された date_offset を超えています。

401

Invalid Key.

x-ca-key リクエストヘッダーが欠落しているか、無効です。

401

Empty Signature.

x-ca-signature リクエストヘッダーが空です。

403

Unauthorized Consumer.

リクエストの呼び出し元にアクセス権限がありません。

413

Request Body Too Large.

リクエストボディが 32 MB を超えています。

413

Payload Too Large.

リクエストボディが、ゲートウェイに設定された DownstreamConnectionBufferLimits を超えています。パラメーター設定ページで DownstreamConnectionBufferLimits を増やすことができます。

説明

DownstreamConnectionBufferLimits を増やすと、ゲートウェイのメモリ使用量が大幅に増加します。慎重に実施してください。