AI Gateway は、グローバル認証とコンシューマーの権限付与をサポートしており、権限のあるリクエストのみがサービスにアクセスできるようにします。このトピックでは、コンシューマーが AI Gateway の認証と権限付与を使用してリソースに安全にアクセスする方法について説明します。
背景情報
グローバル認証と権限付与は、通常、統合ログイン認証などの business-to-consumer (B2C) シナリオに適用されます。対照的に、API のコンシューマー認証は、パートナーへの API アクセスの付与などの business-to-business (B2B) シナリオに適用されます。
比較項目 | グローバル認証と承認 | コンシューマー承認 |
シナリオ | 統合ログイン認証などの B2C シナリオ。 | パートナーへの API アクセスの付与などの B2B シナリオ。 |
主な違い | 認証を有効にすると、権限付与も有効になります。 | 認証を有効にした後、追加の権限付与構成を実行する必要があります。 |
構成エントリ | 。 |
|
認証方式の設定 (JWT 認証を例として使用) |
|
|
権限付与メソッドの設定 | 構成を作成するときに、ブラックリストまたはホワイトリストの [ドメイン] と [パス] を指定します。
|
|
注意事項
ユーザーがコンシューマー認証を有効にすると、認証ポリシーはすぐに有効になります。この時点で API が公開されていても、API にコンシューマーまたは権限付与ルールが設定されていない場合、すべてのアクセスリクエストはデフォルトで拒否されます。
コンシューマー認証と承認を使用する
JWT 認証
JWT 認証フロー
クライアントは、エンドユーザーのユーザー名とパスワードを含む認証リクエストを AI Gateway に送信します。
ゲートウェイはリクエストをバックエンドサービスに転送します。
バックエンドサービスは、リクエストからユーザー名やパスワードなどの検証情報を取得します。情報を検証した後、バックエンドサービスは秘密鍵を使用して標準トークンを生成し、ゲートウェイに返します。
ゲートウェイは、トークンを含む応答をクライアントに返します。クライアントは、このトークンをローカルにキャッシュする必要があります。
クライアントは、トークンを含むビジネスリクエストを AI Gateway に送信します。
ゲートウェイは、設定した公開鍵を使用してリクエスト内のトークンを検証します。トークンが検証されると、ゲートウェイはリクエストをパススルーモードでバックエンドサービスに転送します。
バックエンドサービスはビジネスリクエストを処理し、応答を返します。
ゲートウェイはビジネス応答をクライアントに返します。
以下のセクションでは、トークンの生成方法、クライアントがゲートウェイにリクエストを送信する方法、およびゲートウェイが公開鍵を使用してトークンを検証する方法について説明します。
認証サービスでのトークンの生成
次のセクションでは、Java コードサンプルを使用してトークンを生成する方法について説明します。他のプログラミング言語でキーペアを生成するために、関連ツールを使用することもできます。
Maven プロジェクトを作成し、必要な依存関係を追加します。
まず、Maven プロジェクトを作成し、次の依存関係を追加します。
<dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> <version>0.7.0</version> </dependency>トークンを生成する方法を選択します。
デフォルトの対称鍵サンプルまたは非対称鍵サンプルを使用してトークンを生成できます。要件に基づいてメソッドを選択してください。
デフォルトの対称鍵サンプルを使用したトークンの生成
サンプルコード:
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; import sun.lwawt.macosx.CSystemTray; 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 型である必要があります。 // コンシューマー ID を設定します。 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: コンシューマーを作成するときに使用される JSON Web Key Set (JWKS) です。コンシューマーの作成時に JWKS を記録するか、コンシューマーの作成後にコンシューマーの基本情報ページから取得できます。コンシューマー ID を設定します。これは
claims.setClaim("uid", "11215ac069234abcb8944232b79ae711")で指定されます。コンシューマー ID は、コンシューマーを作成するときにコンソールでデフォルトで生成されます。ビジネスロジックに基づいて ID を変更することもできます。コンシューマーを作成した後、コンシューマーの基本情報ページからコンシューマー ID を取得できます。暗号化アルゴリズムを設定します。これは
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); ...必要に応じて、JWKS の PAYLOAD にカスタムパラメーターを追加できます。
非対称鍵サンプルを使用したトークンの生成
サンプルコード:
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; import sun.lwawt.macosx.CSystemTray; 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 型である必要があります。 // コンシューマー ID を設定します。 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、コンシューマー ID、および有効期限を設定します。設定は、対称暗号化アルゴリズムの場合と同じです。暗号化アルゴリズムを設定します。これは
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256)で指定されます。暗号化アルゴリズムは、JWKS で指定されたアルゴリズムと同じである必要があります。非対称鍵暗号化アルゴリズムの場合、その秘密鍵を使用してデータを暗号化する必要があります。
... jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyJson)).getPrivateKey(); jws.setKey(privateKey); ...必要に応じて、JWKS の
PAYLOADにカスタムパラメーターを追加できます。
クライアントからゲートウェイへのビジネスリクエストの送信
AI Gateway は、ヘッダーでのトークンの受け渡しをサポートしています。リクエストヘッダーの名前とトークンのプレフィックスをカスタマイズできます。リクエストが認証されるとき、キーとプレフィックスは、コンシューマー認証方式に設定されているものと同じである必要があります。
リクエストに JWT が含まれていない場合、HTTP ステータスコード 401 が返されます。
curl http://xxx.hello.com/testリクエストに無効な JWT が含まれている場合、HTTP ステータスコード 401 が返されます。
curl http://xxx.hello.com/test -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ1'リクエストに JWT が含まれているが、JWT によって表されるコンシューマーに API へのアクセス権が付与されていない場合、HTTP ステータスコード 403 が返されます。
# consumer1 は、次のパスで指定された API へのアクセスを許可されていません curl 'http://xxx.example.com/test' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEyMyJ9.eyJpc3MiOiJhYmNkIiwic3ViIjoidGVzdCIsImlhdCI6MTY2NTY2MDUyNywiZXhwIjoxODY1NjczODE5fQ.-vBSV0bKeDwQcuS6eeSZN9dLTUnSnZVk8eVCXdooCQ4'
サーバーでのトークンリクエストの検証
サーバーは、次の 3 つのステップでトークンを検証します。
サーバーはユーザーリクエストを受信すると、リクエストにトークンが含まれているかどうかを確認します。リクエストにトークンが含まれていない場合、リクエストは拒否され、HTTP ステータスコード 401 が返されます。
リクエストにトークンが含まれている場合、サーバーはコンシューマーの JWKS で設定された公開鍵を使用して、トークンが有効かどうかを検証します。トークンが無効であるか、有効期限が切れている場合、リクエストは拒否され、HTTP ステータスコード 401 が返されます。
トークンが有効な場合、サーバーはトークンによって表されるコンシューマーに API へのアクセス権が付与されているかどうかを確認します。
一般的なエラーコード
HTTP ステータスコード | エラーメッセージ | 原因 |
401 | Jwt missing | リクエストヘッダーに JWT がありません。 |
401 | Jwt expired | JWT の期限が切れました。 |
401 | Jwt verification fails | JWT ペイロードの検証に失敗しました。たとえば、iss の値が一致しません。 |
403 | Access Denied | 現在の API にアクセスする権限がありません。 |
API キー認証
モデル API でコンシューマー認証および権限付与ポリシーが有効になっていない場合、API に直接アクセスできます。
モデル API でコンシューマー認証および権限付与ポリシーが有効になっているが、権限が付与されていない場合、HTTP ステータスコード 401 が返されます。
デバッグ手順は呼び出し手順と似ています。このトピックでは、モデル API のデバッグを例として使用します。
API キーの認証情報は、次の 3 つのソースから渡すことができます。
デフォルトのソース: Authorization: <Bearer> Token。
カスタムヘッダー: ヘッダーパラメーターの名前を指定します。
カスタムクエリパラメーター: クエリパラメーターの名前を指定します。
デフォルトソース
モデル API をデバッグするときに、デバッグページの HTTP リクエストヘッダーに API キーを設定して、リクエスト認証を確実にすることができます。手順は次のとおりです。
Authorization フィールドで、Bearer をプレフィックスとして使用します。
Bearer と API キーの間にスペースがあることを確認してください。
カスタムヘッダー
標準のリクエストヘッダーに加えて、カスタム HTTP リクエストヘッダーを定義して特定の情報を渡すことができます。
カスタムクエリパラメーター
リクエスト URL に、カスタムクエリパラメーターを追加して、追加情報や構成を渡すことができます。
関連するエラーコード
HTTP ステータスコード | エラーメッセージ | 原因 |
401 | キー認証チェックによってリクエストが拒否されました。リクエストに複数の API キーが見つかりました。 | リクエストに複数の 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 キーでは API にアクセスできません。 |
403 | Request denied by Key Auth check. Unauthorized consumer. | リクエスターには API にアクセスする権限がありません。 |
関連情報
詳細については、「権限付与管理」をご参照ください。