このトピックでは、Alibaba Cloud API Gateway とマシンツーマシン (M2M) テクノロジーを使用して、サードパーティのアクセス権限を管理する方法について説明します。この方法により、システム間の効率的で安全な自動通信が可能になります。
前提条件
IDaaS に M2M アプリケーションサーバーとクライアントが必要です。
概要
API の M2M 認証を実装するには、次の 3 つのステップに従います。これにより、呼び出し元が信頼され、その権限が制御されるようになります。
Alibaba Cloud API Gateway に API を登録します。
M2M クライアントに権限を付与します。
API Gateway のプラグイン構成を使用して、保護された API を M2M クライアントの権限範囲に関連付けます。
手順
API Gateway への API の登録
API Gateway コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。[グループの作成] をクリックします。
[バックエンドサービス] タブで、[バックエンドサービスの作成] をクリックして、ビジネスサービスのエンドポイントを Alibaba Cloud API Gateway に登録します。これにより、ビジネスサービスの API 操作の管理が簡素化されます。
作成したバックエンドサービスにビジネスサービスのエンドポイントをアタッチします。
バックエンドサービスを作成したら、その中の API 操作を管理します。
作成したバックエンドサービスで、[API の作成] をクリックします。[API の作成] ページが表示されます。
[API の作成] ページで、この例では [セキュリティ認証] を [認証なし] に設定します。次に、[次へ] をクリックします。
[API リクエストの定義] セクションで、リクエストの URI を入力し、HTTP メソッドを選択します。
API のバックエンドサービスを定義するときは、実際のリクエストパスを入力します。呼び出し元が指定されたリクエストパスを使用して API を呼び出すと、リクエストは実際のバックエンドパスにマッピングされます。
レスポンスの ContentType を選択し、API の作成を完了します。
API を作成したら、コンソールでデバッグして、API が利用可能であり、期待どおりに実行されることを確認します。
デバッグ環境を準備します。環境を選択して API を公開します。
リクエストを送信して、ステージング環境で API をデバッグします。この例では、結果は期待どおりです。これにより、API が利用可能であることが確認されます。
M2M クライアントに権限を付与する
IDaaS コンソールで、M2M サーバーアプリケーションに移動します。承認済みアプリケーションセクションで、M2M クライアントアプリケーションを見つけ、必要な権限範囲を付与します。この例では、`user:read:one` 権限範囲がクライアントに付与されます。
API ゲートウェイプラグインの構成
ゲートウェイプラグインを構成して、リクエストの認証と権限付与を実装します。このプロセスにより、M2M の権限範囲が API Gateway に関連付けられます。JWT 認証プラグインとパラメーターアクセス制御プラグインの 2 つのゲートウェイプラグインを作成する必要があります。
JWT 認証プラグインの作成
API Gateway コンソールに移動します。左側のナビゲーションウィンドウで、 を選択します。[プラグイン管理] ページで、[プラグインの作成] をクリックし、[プラグインタイプ] を [JWT 認証] に設定します。
スクリプト構成を入力します。スクリプト内の JSON Web Key (JWK) 情報は、M2M サーバーの公開鍵と一致する必要があります。IDaaS コンソールで、M2M サーバーアプリケーションに移動します。[一般設定] セクションで、[署名検証公開鍵エンドポイント] の URL をコピーします。ブラウザで URL を開き、公開鍵情報を表示します。この例の公開鍵情報を次の図に示します:
コンソールの公開鍵リンク
ブラウザに表示される公開鍵コンテンツ
次のスクリプトの `jwk` セクションを、取得した JWT 公開鍵情報に置き換えます。
置換前のスクリプト構成
--- parameter: id_token # 指定されたパラメーターから JWT を取得します。これは API パラメーターに対応します。 parameterLocation: query # API がマッピングモードの場合はオプションです。パススルーモードでは必須です。JWT を読み取る場所を指定します。`query` と `header` のみがサポートされています。 bypassEmptyToken: false # JWT が空の場合に検証をパスさせるかどうかを指定します。 claimParameters: # クレームパラメーターの変換。ゲートウェイは JWT クleームをバックエンドパラメーターにマッピングします。 - claimName: aud # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: aud # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 - claimName: scope # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: scope # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 - claimName: client_id # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: client_id # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 preventJtiReplay: false # `jti` のリプレイ防止チェックを有効にするかどうかを指定します。デフォルト: false。 # # 以下の内容は置き換える必要があります。 jwk: kty: RSA e: AQAB use: sig kid: O8fpdhrViq2zaaaBEWZITz # JWK が 1 つだけ構成されている場合、kid はオプションです。ただし、JWT に kid が含まれている場合、ゲートウェイはその一貫性を検証します。 alg: RS256 n: qSVxcknOm0uCq5vGsOmaorPDzHUubBmZZ4UXj-9do7w9X1uKFXAnqfto4TepSNuYU2bA_-tzSLAGBsR-BqvT6w9SjxakeiyQpVmexxnDw5WZwpWenUAcYrfSPEoNU-0hAQwFYgqZwJQMN8ptxkd0170PFauwACOx4Hfr-9FPGy8NCoIO4MfLXzJ3mJ7xqgIZp3NIOGXz-GIAbCf13ii7kSStpYqN3L_zzpvXUAos1FJ9IPXRV84tIZpFVh2lmRh0h8ImK-vI42dwlD_hOIzayL1Xno2R0T-d5AwTSdnep7g-Fwu8-sj4cCRWq3bd61Zs2QOJ8iustH0vSRMYdP5oYQ置換後のスクリプト構成
--- parameter: id_token # 指定されたパラメーターから JWT を取得します。これは API パラメーターに対応します。 parameterLocation: query # API がマッピングモードの場合はオプションです。パススルーモードでは必須です。JWT を読み取る場所を指定します。`query` と `header` のみがサポートされています。 bypassEmptyToken: false # JWT が空の場合に検証をパスさせるかどうかを指定します。 claimParameters: # クレームパラメーターの変換。ゲートウェイは JWT クレームをバックエンドパラメーターにマッピングします。 - claimName: aud # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: aud # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 - claimName: scope # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: scope # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 - claimName: client_id # クレーム名。パブリックおよびプライベートクレームがサポートされています。 parameterName: client_id # マッピングされたパラメーターの名前。 location: query # マッピングされたパラメーターの場所。`query`、`header`、`path`、`formData` がサポートされています。 preventJtiReplay: false # `jti` のリプレイ防止チェックを有効にするかどうかを指定します。デフォルト: false。 # # JSON Web Key の公開鍵 jwk: kty: RSA e: AQAB use: sig kid: AUTHSKEY7Ph6QS83xkN76oRwvZsJT68ejJ4PdAXmk # JWK が 1 つだけ構成されている場合、kid はオプションです。ただし、JWT に kid が含まれている場合、ゲートウェイはその一貫性を検証します。 alg: RS256 n: i1tIYhXvfilaJi8kaIS8EpgsnDp6G4c1lEg2qRD_-1lY8jOIWAVcetq89itl7rjFJ9gmbKGBMJoutaxGHtbAkY0aINkg1_n_0NnNTZDt2UC1UNJaZh12bkYyubRLA_t6JS8PVSr5bpse1SErvDiumqU9CjxBUCd4K8R0ALxOwup6yY5gVT4Juia1bEVGPlJ-RnuMvXXbVmwuklKTiWNfBFw1lCDPftfzKVEDTXt4VphAWOT-CyZKJ8hcYiTnd_VaAYxjMQSCxmE-utrdXGhyDUaQobs0myvD2eJfzcSWG-qOTC7Hin8bvXIQ_v9BkJO3D6uoLpB14XQozWVTXaPTIw
パラメーターアクセス制御プラグインの作成
[プラグインタイプ] を [パラメーターアクセス制御] に設定します。
スクリプトコンテンツを入力して、アクセスの制御を実装します。次のスクリプトでは、`condition` を使用して検証ポリシーを実装します。
右側のスクリプトは、検証の例として clientId と scope を使用します。
condition: "$clientId = 'app_m7hfgn66xkyyxlhpkiw5kjenhy' and $scope like '%user:read:one%'"
clientId は M2M クライアントのアプリケーション ID です。
scope は M2M クライアントの権限範囲です。必要に応じて、これら 2 つのパラメーターを置き換えてください。
--- # # この例では、API リクエストパスが `/{userId}/...` であると仮定します。 # API は JWT 認証を使用し、JWT には userId と userType の 2 つのクレームが含まれています。 # このプラグインの検証条件は次のとおりです: # - userType=admin の場合、すべてのパスが許可されます。 # - userType=user の場合、一致する /{userId} パスを持つリクエストのみが許可されます。 parameters: scope: "Token:scope" clientId: "Token:client_id" # # ルールは順次処理されます。条件が `true` または `false` を返すかに基づいて、`ifTrue` または `ifFalse` ロジックが実行されます。 # `ALLOW` は即座に成功となります。`DENY` は即座にクライアントにエラーコードを返します。 # `ALLOW` も `DENY` もトリガーされない場合、次のルールが実行されます。 rules: - name: checkScope condition: "$clientId = 'app_m7hfgn66xkyyxlhpkiw5kjenhy' and $scope like '%user:read:one%'" ifFalse: "DENY" statusCode: 403 errorMessage: "No permission by client id: ${clientId}" responseHeaders: Content-Type: application/json X-IDaaS-clientId: ${clientId} X-IDaaS-scope: ${scope} responseBody: | <Reason>No permission by client id: ${clientId}</Reason>
API へのプラグインのバインド
2 つのプラグインを作成したら、それらを API 操作にバインドします。これにより、権限範囲と API 操作の間にマッピングが作成されます。この例では、このバインドにより、`user:read:one` 権限範囲で `hello` API へのアクセスを制御できます。
2 つのプラグインのそれぞれについて、[操作] 列の [API のバインド] をクリックして、プラグインを API 操作にバインドします。
検証と使用法
手順を完了したら、M2M サーバーから権限付与トークンを取得します。次に、呼び出し元はこのトークンを使用してビジネス API にアクセスします。
トークンの取得
client_secret_post 認証方式を使用してトークンを取得します。次のステップに従ってください:
M2M サーバーの Issuer URL をコピーします。
次のリクエストパラメーターを入力し、Issuer URL にリクエストを送信します。
パラメーター
説明
client_secret
M2M クライアントのアプリケーションシークレット。
client_id
M2M クライアントのアプリケーション ID。
grant_type
静的な値 `client_credentials`。
scope
M2M サーバーのオーディエンス識別子と権限範囲。この例では、
https://xxxx.aliyunidaas.com|user:read:one
API のデバッグ
グループの第 2 レベルドメインをリクエスト URL として使用します。このドメインはグループの詳細で確認できます。
入力パラメーターは、JWT 認証プラグインで定義したトークンの場所とトークンパラメーター識別子です。この例では、入力パラメーターのキーは `id_token` で、値は前のステップで取得したトークンです。
リクエストは期待どおりの結果を返します。これにより、M2M クライアントが `hello` API にアクセスする権限を持っていることが確認されます。
参考資料
M2M アプリケーションの動作原理の詳細については、「M2M アプリケーション (マシンツーマシン権限管理)」をご参照ください。
Alibaba Cloud Resource Access Management (RAM) を使用して AccessKey なしでアクセスを実装する方法については、「AccessKey なしでのアクセスのための構成手順」をご参照ください。