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

API Gateway:コンシューマー認証と認可

最終更新日:Jun 09, 2026

クラウドネイティブ API Gateway は、グローバル認証、ルートレベル認証、およびコンシューマー認可をサポートしています。このトピックでは、各認証方法を設定し、特定のルートと API へのアクセスをコンシューマーに認可する方法について説明します。

背景

グローバル認証は、統合ログインなどの B2C シナリオに適しています。ルートと API のコンシューマー認証は、パートナーに API へのアクセス権を付与するなどの B2B シナリオに適しています。

項目

グローバル認証

ルート認証とコンシューマー認可

ユースケース

統合ログイン認証などの B2C シナリオ。

パートナーに API アクセス権を付与するなどの B2B シナリオ。

主な違い

認証を有効にすると、認可も有効になります。

認証を有効にした後、別途認可を設定する必要があります。

設定パス

インスタンス > Security Management > Global Authentication

  1. [API Management] > HTTP API 詳細 > ルート管理 > ポリシー設定 > コンシューマー認証

  2. [API Management] > WebSocket API 詳細 > ルート管理 > ポリシー設定 > コンシューマー認証

  3. [API Management] > REST API 詳細 > ポリシーのアタッチ > コンシューマー認証

  4. Consumers > [コンシューマー詳細] > [コンシューマー認可]

認証方法の設定 (JWT 認証の例)

  1. 設定を作成する際、グローバル JWKS 設定を指定してください。

  2. JWT を検証するために、issuesub フィールドを入力します。

  1. コンシューマー設定を作成する際は、そのコンシューマーに対応する JWKS 設定を指定してください。

  2. コンシューマー識別子を指定して、JWT が正しいコンシューマーのものであることを検証します。デフォルトでは、これは payload 内の uid フィールドですが、カスタマイズ可能です。

認可方法の設定

設定を作成する際は、ブラックリストまたはホワイトリスト用のDomain NamePathのリストを指定します。

  • [Blacklist Mode]: リスト上の Domain NamePath へのリクエストには認証が必要です。他のすべてのリクエストには必要ありません。

  • [Whitelist Mode]: リストにあるドメインと Path へのリクエストは認証が不要です。その他すべてのリクエストには認証が必要です。

  1. ルートまたは API の Configure Policy の設定で、Authentication を有効にします。

  2. [コンシューマー認可] で、認証されたルートまたは API へのアクセス権をコンシューマーに付与して、認可プロセスを完了します。

使用上の注意

コンシューマー認証を有効にすると、ポリシーは直ちに有効になります。公開済みのルートまたは API にコンシューマーまたは認可ルールが設定されていない場合、ゲートウェイはデフォルトではすべてのリクエストを拒否します。

コンシューマー認証と認可の使用

JWT 認証

JWT 認証ワークフロー

  1. クライアントは、通常エンドユーザーのユーザー名とパスワードを含む認証リクエストをゲートウェイに送信します。

  2. ゲートウェイは、リクエストをバックエンドサービスに転送します。

  3. バックエンドは認証情報を検証します。検証に成功すると、秘密鍵を使用してトークンを生成し、そのトークンをゲートウェイに返します。

  4. ゲートウェイは、トークンをクライアントに返します。クライアントは、このトークンをローカルにキャッシュします。

  5. クライアントは、キャッシュされたトークンを含むビジネスリクエストをゲートウェイに送信します。

  6. ゲートウェイは、設定された公開鍵を使用してトークンを検証します。有効な場合、ゲートウェイはリクエストをバックエンドに転送します。

  7. バックエンドは、リクエストを処理してレスポンスを返します。

  8. ゲートウェイは、レスポンスをクライアントに転送します。

以下のセクションでは、トークンの生成方法、ゲートウェイへのリクエストの送信方法、および設定された公開鍵を使用したトークンの検証方法について説明します。

トークンの生成

以下の Java の例では、トークンの生成方法を示しています。他の言語でも同様のツールを使用できます。

  1. Maven プロジェクトを作成し、依存関係を追加します。

    プロジェクトに以下の依存関係を追加します。

    <dependency>
        <groupId>org.bitbucket.b_c</groupId>
        <artifactId>jose4j</artifactId>
        <version>0.7.0</version>
    </dependency>
  2. トークンを生成する方法を選択します。

    対称キーまたは非対称キーのいずれかを使用してトークンを生成できます。

    対称キー

    サンプルコード:

    package org.example;
    
    import java.io.UnsupportedEncodingException;
    import java.security.PrivateKey;
    
    import org.jose4j.base64url.Base64;
    import org.jose4j.json.JsonUtil;
    import org.jose4j.jwk.OctJwkGenerator;
    import org.jose4j.jwk.OctetSequenceJsonWebKey;
    import org.jose4j.jws.AlgorithmIdentifiers;
    import org.jose4j.jws.JsonWebSignature;
    import org.jose4j.jwt.JwtClaims;
    import org.jose4j.jwt.NumericDate;
    import org.jose4j.keys.HmacKey;
    import org.jose4j.lang.JoseException;
    
    public class Main {
        public static void main(String[] args) throws JoseException, UnsupportedEncodingException {
            // このトピックの例を使用します。
            String privateKeyJson = "{\n"
                    + "    \"k\": \"VoBG-oyqVoyCr9G56ozmq8n_rlDDyYMQOd_DO4GOkEY\",\n"
                    + "    \"kty\": \"oct\",\n"
                    + "    \"alg\": \"HS256\",\n"
                    + "}";
            JwtClaims claims = new JwtClaims();
            claims.setGeneratedJwtId();
            claims.setIssuedAtToNow();
            // 有効期限を 7 日未満に設定します。
            NumericDate date = NumericDate.now();
            date.addSeconds(120*60);
            claims.setExpirationTime(date);
            claims.setNotBeforeMinutesInThePast(1);
            // カスタムパラメーターを追加します。すべての値は String 型である必要があります。
            // コンシューマー識別子を設定します。
            claims.setClaim("uid", "11215ac069234abcb8944232b79ae711");
            JsonWebSignature jws = new JsonWebSignature();
            // 暗号化アルゴリズムを設定します。
            jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
            jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
            jws.setPayload(claims.toJson());
            String jwtResult = jws.getCompactSerialization();
            System.out.println("Generate Json Web token , result is \n " + jwtResult);
        }
    }

    コードの設定:

    • privateKeyJson: コンシューマーの作成時に使用する JWKS です。コンシューマーの作成時に JWKS を保存するか、コンシューマーの基本設定ページから取得します。

    • コンシューマー識別子を設定します。ステートメントは claims.setClaim("uid", "11215ac069234abcb8944232b79ae711") です。この識別子は、コンシューマーの作成時に自動生成されますが、変更することもできます。コンシューマーの基本設定ページから取得することもできます。

    • 暗号化アルゴリズムを設定します。ステートメントは jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256) です。このアルゴリズムは、JWKS のアルゴリズムと一致する必要があります。

      説明

      サポートされている暗号化アルゴリズムには、ES256、ES384、ES512、RS256、RS384、RS512、PS256、PS384、PS512、HS256、HS384、HS512、および EdDSA が含まれます。

      対称暗号化の場合、"k" の値をデコードする必要があります。

      jws.setKey(new HmacKey(Base64.decode(JsonUtil.parseJson(privateKeyJson).get("k").toString())));
    • 有効期限を設定します。トークンは 7 日以内に期限切れになる必要があります。期限切れ後は、新しいトークンを生成してください。

      ...
          NumericDate date = NumericDate.now();
          date.addSeconds(120*60);
          claims.setExpirationTime(date);
          claims.setNotBeforeMinutesInThePast(1);
      ...
    • 必要に応じて、JWT のペイロードにカスタムパラメーターを追加できます。

    非対称キー

    サンプルコード:

    package org.example;
    
    import java.security.PrivateKey;
    import org.jose4j.json.JsonUtil;
    import org.jose4j.jws.AlgorithmIdentifiers;
    import org.jose4j.jws.JsonWebSignature;
    import org.jose4j.jwt.JwtClaims;
    import org.jose4j.jwt.NumericDate;
    import org.jose4j.lang.JoseException;
    import org.jose4j.jwk.RsaJsonWebKey;
    
    public class Main {
        public static void main(String[] args) throws JoseException {
            // JWK 形式のサンプルキー。
            String privateKeyJson = "{"
                    + "\"kty\":\"RSA\","
                    + "\"n\":\"u-8lR9lyRhu8tl4vRxOl7yfshssx5jRstabc9n4Rxrz102Z7TPFYrXBZHgf67Y0d-zx9tWd5j91WZxLHv4K6VWPN7zEWEQNn3vUg76dPHPzVkZJWziFPS1EvS4a2gRZdrE4nPogaQ72WySVC0yUF2fL0NKeOclD__coCFxn4QQjcDXyu_CUbI_FuDcdw267mVjjylAaFvOZHH0pXsV8m5zXlpc2aiemWYQJD9MtWRcoKlexWMkTwbEqW5-NWAl0Uo202ahDA1NiaQ98Ch4nw6g2E1GvwxxHkbvMuZcs5z8F5Ct_w0IPtvY7ngSyEN-WCU40oj-C5NUCy_73FpXXdWQ\","
                    + "\"e\":\"AQAB\","
                    + "\"d\":\"Uxg1IqSZazg-Y2AXhVTBrJG5egwD3yZU3qiN0IsDbx0DkFoisG2R6PXg4W9j2n7nv7sKVhgPXrXdyys5mIrDuperaVQJzrHzzlgSHQSb7VQ5Vekfanq95a5avAkvTrpF5raTkYl6G3OLZRqNhnA7Oxe6NEHVsOPxnBQignZgFtiBtCSZY4RVH6Dx4jFfBBNMC9ifyLWLpHut7eczvxI412nBkxgtEjSeFe083NlumO_ZYHbijPcQf5zFWPLEj2EvlgbSwhjc-uSAF4OljAyG_DHZYvztEIGMdxMgBHgwtEvCfzS6PeUgvUR-SB7m_L8z4gjz6TlpSYe3CnZqE69KdQ\","
                    + "\"p\":\"9mNw8U_GxbcSknueUeFFSU9wKD9E9P2ZO5RP5d7o3qGUXOfbrH_g5GMH3YJiPBDZs_2BYFrAACOY4YM-QTiXWVs4xS3OeD8AdH3wEXR_3DMEkOez3cNq3Jy3ZJabm7IUnPMIWv5gpIHghcx0YTtM5RabSgexLMKh2-6sB466378\","
                    + "\"q\":\"w0PzXI_8Q5jv15OUq-dV_Z0kp91Icumf6PEERZN4v3i3VolLBnamMiIQiF74ywclKpZmtfOQTfyL41Xj2vbm2Aus6akRsU3NhQlVtIQTzHWUuEQgMIJYDK7--FzEcZORm1qBiEffiWv6U-slyCcLcNDNT-wjMX8BrS4oWHIoCOc\","
                    + "\"dp\":\"fRRiY76yE_EqVn63Eq4ftGXFdEkaQpzzS1GxderBoTO506hI1rtcedTkS0lDgWa0fjE1mqq3SdrIY8NyuT13Z_9tRHxKkrS5EGpWkyXnOuwTZ1SY9P2dpD1SxJfIizPOTxb5qOf2O81LI-F1O18VXD8rultJUIXGEZaKcpO8vpU\","
                    + "\"dq\":\"V6EP_vMzD5b707AMYVURFx7Fi3vX_pHvzJcVBrBW2P6wsGouvDjU_tygtMKCPoL3X_RdJbynfwgeMyihd-ujz0L2F2pjYUF8QP7ecoNvays9UbBpDbwBDbge_pCLLDlAeAqW5PT0UXSew7hcnUVAciGSchKT_Kt1siVrv72DT_M\","
                    + "\"qi\":\"w5fENzxOivbbbUbawAWSuLgWPtvbTKn2XuPzwr_JzZH08-nadWwQFChcvAiCs8V-306TQOh8NfY308QpGDIq-iRfrS7CEePOjRzpHJfsaQ1IFQqzgDZ9VGdJRDlZqRHx0DbqwMlleVKTC6ER6varalbr4lKU-ZPUQLCzj0e4PMs\""
                    + "}";
    
            JwtClaims claims = new JwtClaims();
            claims.setGeneratedJwtId(); // JTI (JWT ID) を自動生成します。
            claims.setIssuedAtToNow();  // 発行時刻 (iat) を現在の時刻に設定します。
    
            // 有効期限を 7 日未満に設定します。
            NumericDate date = NumericDate.now();
            date.addSeconds(120 * 60); // 有効期限を現在から 120 分後に設定します。
            claims.setExpirationTime(date);
            claims.setNotBeforeMinutesInThePast(1); // not before (nbf) 時刻を 1 分前に設定します。
    
            // カスタムパラメーターを追加します。すべての値は String 型である必要があります。
            // コンシューマー識別子を設定します。
            claims.setClaim("uid", "11215ac069234abcb8944232b79ae711");
    
            JsonWebSignature jws = new JsonWebSignature();
            // 暗号化アルゴリズムを RSA-SHA256 に設定します。
            jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
    
            // 秘密鍵を解析して署名者に設定します。
            PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey();
            jws.setKey(privateKey);
    
            // ペイロードコンテンツを設定します。
            jws.setPayload(claims.toJson());
    
            // JWT を生成します。
            String jwtResult = jws.getCompactSerialization();
            System.out.println("Generate Json Web token , result is \n " + jwtResult);
        }
    }
    

    コードの設定:

    • privateKeyJson、コンシューマー識別子、および有効期限の設定は、対称暗号化の場合と同様です。

      ステートメント jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256) を使用して暗号化アルゴリズムを設定します。このアルゴリズムは、JWKS のアルゴリズムと一致する必要があります。

      非対称暗号化アルゴリズムの場合、暗号化には秘密鍵を使用する必要があります。

      ...
          jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
          PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey();
          jws.setKey(privateKey);
      ...
    • JWT の PAYLOAD にカスタムパラメーターを追加できます。

ビジネスリクエストの送信

クラウドネイティブ API Gateway は、リクエストヘッダーでトークンを渡すことをサポートしています。ヘッダー名とトークンプレフィックスをカスタマイズできます。リクエスト内のキーとプレフィックスは、コンシューマーの認証方法で設定されたものと一致する必要があります。

  • JWT を含まないリクエストの場合、401 エラーが返されます。

    curl  http://xxx.hello.com/test
  • 無効な JWT を含むリクエストの場合、401 エラーが返されます。

    curl  http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ1'
  • リクエストに有効な JWT が含まれているが、コンシューマーが API またはルートに対して認可されていない場合、403 エラーが返されます。

    # consumer1 は、指定されたパスのルートまたは API に対して認可されていません。
    
    curl  'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'

サーバー側のトークン検証

トークン検証には 3 つのステップがあります。

  1. リクエストにトークンが含まれているかどうかを確認します。含まれていない場合は、401 で拒否します。

  2. コンシューマーの JWKS の公開鍵を使用して、トークンの有効性と有効期限を検証します。無効または期限切れの場合は、401 で拒否します。

  3. コンシューマーが要求された API またはルートにアクセスする権限を持っているかどうかを確認します。

一般的なエラーコード

HTTP ステータスコード

エラーメッセージ

説明

401

Jwt missing

リクエストヘッダーに JWT がありません。

401

Jwt expired

JWT の有効期限が切れています。

401

Jwt verification fails

JWT ペイロードの検証に失敗しました。たとえば、iss の不一致が原因です。

403

Access Denied

現在のルートにアクセスする権限がありません。

AK/SK (HMAC) 認証

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

クライアントは、3 つのステップで署名を生成します。

  1. 署名対象文字列の抽出: 元のリクエストから主要なデータを抽出して、署名用の文字列を形成します。

  2. 署名の作成: SK を使用して署名対象文字列を暗号化し、最終的な署名を生成します。

  3. 署名の追加: すべての署名関連ヘッダーを元の HTTP リクエストに追加して、最終的なリクエストを形成します。

ステップ 1: 署名対象文字列の抽出

HTTP リクエストから主要なデータを抽出し、次の形式で署名対象文字列として組み立てます。

HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters

これらの 7 つのフィールドが署名対象文字列を構成し、改行文字 (\n) で区切られます。Headers フィールドが空の場合、その後に改行は必要ありません。その他の空のフィールドについては、改行文字を含めます。署名は、大文字と小文字を区別します。各フィールドは次のように抽出されます。

  • HTTPMethod: HTTP メソッド (大文字)。例: POST

  • Accept: Accept ヘッダーの値。空にすることも可能です。Accept ヘッダーを明示的に設定することを推奨します。空の場合、一部の HTTP クライアントはデフォルト値として */* を設定するため、署名検証が失敗します。

  • Content-MD5: Content-MD5 ヘッダーの値。空にすることも可能です。フォーム以外のボディを持つリクエストに対してのみ計算します。以下の Java コードは、Content-MD5 値の計算方法を示しています。

    String contentMD5 = 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-SignatureX-Ca-Signature-HeadersAcceptContent-MD5Content-Type、および Date

  • PathAndParameters: パス、クエリパラメーター、およびフォームパラメーターが含まれます。次のように構成されます。

    Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
    重要
    • 連結する前に、クエリパラメーターとフォームパラメーターのキーをアルファベット順にソートします。

    • クエリパラメーターとフォームパラメーターが空の場合は、? を付けずに Path を直接使用します。

    • パラメーターの値が空の場合は、キーのみを含めます。等号 (=) は含まれません。

    • クエリまたはフォームに配列パラメーター (同じキー、異なる値) が含まれている場合は、署名計算に最初の値を使用します。

ステップ 2: 署名の作成

署名対象文字列を暗号化およびエンコードして、最終的な署名を生成します。次の例では、stringToSign は抽出された文字列、secret は AK/SK 設定の SK、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 バイト配列にエンコードし、暗号化して、結果を Base64 エンコードして署名を生成します。

ステップ 3: リクエストへの署名の追加

署名検証のために、HTTP リクエストに次の 4 つのヘッダーを含めます。

  • x-ca-key: AK/SK 認証設定の AK。

  • x-ca-signature-method: 署名アルゴリズム。有効な値は HmacSHA256 または HmacSHA1 です。これはオプションであり、デフォルトは HmacSHA256 です。

  • x-ca-signature-headers: 署名に含まれるすべてのヘッダーキーのカンマ区切りリスト。これはオプションです。

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

サーバー側の署名検証

サーバー側の署名検証は次のように機能します。

  1. 署名対象文字列の抽出: 受信したリクエストから主要なデータを抽出して、署名用の文字列を形成します。

  2. SK の取得: リクエストから AK を読み取り、それを使用して対応する SK を取得します。

  3. 署名の計算: 同じ暗号化アルゴリズムと取得した SK を使用して署名対象文字列を暗号化し、サーバー側の署名を生成します。

  4. 署名の検証: リクエストからクライアント側の署名を読み取り、サーバー側の署名と比較して一致を確認します。

トラブルシューティング

署名検証が失敗すると、サーバーは X-Ca-Error-Message レスポンスヘッダーに署名対象文字列 (StringToSign) を返します。サーバー側の StringToSign とローカルで計算したものを比較してください。一致する場合は、正しい SK を使用したかどうかを確認してください。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 ステータスコード

エラーメッセージ

説明

401

Invalid Key

x-ca-key ヘッダーがないか、キーが無効です。

401

Empty Signature

x-ca-signature ヘッダーがありません。

400

Invalid Signature

x-ca-signature ヘッダー内の署名が、サーバーによって計算された署名と一致しません。

400

Invalid Content-MD5

Content-MD5 ヘッダーが正しくありません。

400

Invalid Date

Date ヘッダーから計算された時間オフセットが、設定された date_offset を超えています。

413

Request Body Too Large

リクエストボディのサイズが 32 MB の制限を超えています。

413

Payload Too Large

リクエストボディが、グローバルに設定された DownstreamConnectionBufferLimits を超えています。

403

Unauthorized Consumer

リクエストの呼び出し元は認可されていません。

サンプルコード (Go)

go
package main
import (
	"bytes"
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)
func generateHMACSignature(toSign string, key string) (string, error) {
	h := hmac.New(sha256.New, []byte(key))
	h.Write([]byte(toSign))
	return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil
}
func test(accessKey, secretKey string) {
	body := `{"hello":"world"}`
	h := md5.New()
	h.Write([]byte(body))
	payload := base64.StdEncoding.EncodeToString(h.Sum(nil))
	headers := map[string]string{
		"accept":                 "application/json",
		"content-type":           "application/json",
		"date":                   time.Now().UTC().Format(time.RFC1123),
		"x-ca-key":               accessKey,
		"foo":                    "bar",
		"x-ca-signature-headers": "foo",
		"content-md5":            payload,
	}
	sts := strings.Join([]string{"POST", headers["accept"], headers["content-md5"], headers["content-type"], headers["date"], "foo:bar", "/post"}, "\n")
	fmt.Printf("String to sign is: %s\n", strings.ReplaceAll(sts, "\n", "#"))
	sign, _ := generateHMACSignature(sts, secretKey)
	fmt.Printf("Signed string is: %s\n", sign)
	headers["x-ca-signature"] = sign
	req, _ := http.NewRequest("POST", "http://localhost:8080/post", bytes.NewBufferString(body))
	for k, v := range headers {
		req.Header.Add(k, v)
	}
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("read body error")
	}
	defer resp.Body.Close()
	fmt.Println("Headers are as follows:")
	for k, v := range resp.Header {
		// 署名検証が失敗した場合、X-Ca-Error-Message レスポンスヘッダーには
		// サーバー側の署名対象文字列が含まれており、トラブルシューティングに使用できます。
		fmt.Printf("  %s: %s\n", k, v)
	}
	respBody, _ := io.ReadAll(resp.Body)
	fmt.Println(string(respBody))
}
func main() {
	test("appKey", "appSecret")
}

API キー認証

ゲートウェイは、設定された認証情報ソースに基づいてリクエストを認証します。プロセスは API とルートで同様です。以下の例ではルートを使用します。

API キーには 3 つの認証情報ソースタイプがあります。

  1. デフォルトの認証情報ソース: Authorization: Bearer <token>

  2. カスタムヘッダー: ヘッダー名を指定します。

  3. カスタムクエリパラメーター: クエリパラメーター名を指定します。

デフォルトの認証情報ソース

リクエストがルート abc に一致すると仮定します。API キーは、Authorization ヘッダーに Bearer プレフィックス (末尾にスペースがあることに注意) を付けて提供されます。

curl  http://xxx.test.com/test -H 'Authorization: Bearer 2bda943c-ba2b-11ec-ba07-00163e1250b5'

リクエストヘッダーに API キーを設定する

curl  http://xxx.test.com/test -H 'x-api-key: 2bda943c-ba2b-11ec-ba07-00163e1250b5'

カスタムヘッダーソース

リクエストがルート abc に一致し、API キーがカスタムヘッダーにあると仮定します。

  • API キーが間違った場所にある場合 (たとえば、設定されたカスタムヘッダーではなくクエリパラメーターとして)、リクエストは 401 で拒否されます。

    curl  http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5
  • ポリシーが有効になっているが、コンシューマーが認可されていない場合、リクエストは 403 で拒否されます。

    curl  http://xxx.test.com/test -H 'x-api-key: 2bda943c-ba2b-11ec-ba07-00163e1250b5'

カスタムクエリパラメーター

リクエストがルート abc に一致し、API キーが URL パラメーターにあると仮定します。

  • 設定されたクエリパラメーターに API キーが含まれていない場合、リクエストは 401 で拒否されます。

    curl  http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5
  • ポリシーが有効になっているが、コンシューマーが認可されていない場合、リクエストは 403 で拒否されます。

    curl  http://xxx.test.com/test?apikey=2bda943c-ba2b-11ec-ba07-00163e1250b5

関連するエラーコード

HTTP ステータスコード

エラーメッセージ

説明

401

Request denied by Key Auth check. Multi API key found in request.

リクエストに複数の API キーが提供されました。

401

Request denied by Key Auth check. No API key found in request.

リクエストに API キーが提供されませんでした。

401

Request denied by Key Auth check. Invalid API key.

提供された API キーはアクセスを許可されていません。

403

Request denied by Key Auth check. Unauthorized consumer.

リクエストの呼び出し元は認可されていません。

関連ドキュメント

認可管理で、API を認可および管理できます。