gRPC サービスでサービス アカウントを使用してサービス間認証を実装できます。認証されたリクエストをサポートするように gRPC サービスで Extensible Service Proxy(ESP)を構成する方法や、gRPC クライアントからサービスを呼び出す方法など、サービス間認証を詳細な例を挙げて説明します。
Cloud Endpoints API に対して認証済みの呼び出しを行うには、呼び出し元のサービスでサービス アカウントを設定し、呼び出しに認証トークンを含めて送信する必要があります。呼び出し元では、Google ID トークンを使用するか、呼び出し元のサービス アカウントのみで署名されたカスタムの JSON ウェブトークン(JWT)を使用する必要があります。ESP は、JWT 内の iss
クレームがサービス構成の issuer
設定と一致することを検証します。ESP は、サービス アカウントに付与されている Identity and Access Management の権限を確認しません。
この例では、最も簡単な形式のサービス間認証を設定して使用します。クライアントは、Google Cloud サービス アカウントを使用して、認証を行う JWT を生成します。他の認証方法のアプローチも似ていますが、有効な認証トークンを取得するためのクライアント側の処理は、使用する認証方法によって異なります。
始める前に
このガイドでは、チュートリアルで使用した Bookstore の例を使用します。
gRPC のサンプルコードがホストされる git リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
作業ディレクトリに移動します。
cd python-docs-samples/endpoints/bookstore-grpc/
プロジェクトがまだ存在しない場合は、チュートリアルの手順を行ってプロジェクトを設定します。
この例では、Google Kubernetes Engine へのデプロイを使用しますが、認証の設定は Compute Engine の場合も同じです。
この例では、参照されている 2 つの Google Cloud Platform プロジェクトがあります。
- サービス プロデューサー プロジェクト。Cloud Endpoints for gRPC サービスを所有するプロジェクト。
- サービス ユーザー プロジェクト。gRPC クライアントを所有するプロジェクト。
ユーザー サービス アカウントとキーの作成
ユーザー プロジェクトのサービス アカウントとキーを作成するには:
- Google Cloud Console で [API とサービス] に移動します。 ユーザー プロジェクト内にいることを確認します。
- [認証情報] ページの [認証情報を作成] プルダウン リストで、[サービス アカウント キー] を選択します。
[サービス アカウントキーの作成] ページを開きます。使用するサービス アカウントがすでに存在する場合は、そのアカウントを選択します。それ以外の場合は、[サービス アカウント] プルダウン リストで [新しいサービス アカウント] を選択し、アカウント名を入力します。
対応するサービス アカウント ID が作成されます。以降のセクションで必要になるので、この ID を書き留めておきます。例:
service-account-name@YOUR_PROJECT_ID.iam.gserviceaccount.com
[役割] プルダウン リストをクリックし、次の役割を選択します。
- サービス アカウント > サービス アカウント ユーザー
- サービス アカウント > サービス アカウント トークン作成者
キーのタイプとして [JSON] が選択されていることを確認します。
[作成] をクリックします。サービス アカウントの JSON キーファイルが、ローカルマシンにダウンロードされます。このキーファイルはトークンを生成するために後で使用するため、安全な場所に保管されていることを確認し、その場所を記録してください。
サービス用の認証の構成
このセクションのすべてのステップで、プロデューサー プロジェクトを使用します。
gRPC API 構成での認証のセットアップ
ESP 用の認証は、gRPC API の YAML 構成ファイル内にある authentication
セクションで構成します。サンプル サービス用の認証の構成は api_config_auth.yaml
にあります。
providers
セクションでは、使用する認証プロバイダを指定します。この例では、Google サービス アカウントを認証プロバイダとして使用することを指定しています。rules
セクションでは、サービスのすべてのメソッドへのアクセスにこのプロバイダのトークンが必要であることを指定しています。
クローンのリポジトリに含まれるこのファイルの独自のコピーで、次のようにします。
MY_PROJECT_ID
をプロデューサー プロジェクトの ID に変更します。authentication
セクションのSERVICE-ACCOUNT-ID
(issuer
とjwks_uri
の両方の値にあります)を、前のセクションで記録しておいたユーザー サービス アカウント ID に変更します。これにより、この特定のサービス アカウントからの有効なトークンを提供するユーザーにサービスへのアクセスを許可するよう、ESP に指示します。- 必要に応じて、
providers
要素の下にjwt_locations
を追加します。この値を使用して、カスタム JWT の場所を定義できます。デフォルトの JWT の場所は、Authorization
メタデータ(接頭辞「Bearer」)とX-Goog-Iap-Jwt-Assertion
メタデータです。
次のステップのためにファイルを保存します。
構成とサービスのデプロイ
次の手順は、GKE での gRPC のスタートガイドのものと同じです。
Endpoints にサービス構成をデプロイします。チュートリアルでこの処理を行った場合でも、これは別の構成であるため、再度行う必要があります。返されるサービス名を記録しておきます。
gcloud endpoints services deploy api_descriptor.pb api_config_auth.yaml --project PRODUCER_PROJECT
まだ行っていない場合は、コンテナ クラスタを作成し、そのクラスタに対して
kubectl
を認証します。サンプルの API と ESP をクラスタにデプロイします。プロデューサー プロジェクトとユーザー プロジェクトを個別に使用する場合は、最初に、
gcloud
コマンドライン ツール内で適切なプロジェクトを設定してあることを確認します。gcloud config set project PRODUCER_PROJECT
gRPC クライアントからの認証されたメソッドの呼び出し
最後に、クライアント側で、サービス アカウント キーを使用して JWT トークンを生成してから、そのトークンを使用して認証された Bookstore メソッドを呼び出すことができます。まず、トークンを生成し、サンプル クライアントを実行するために必要な Python 要件をインストールします。クローンのクライアントの python-docs-samples/endpoints/bookstore-grpc
フォルダに移動し、次のコマンドを実行します。
virtualenv bookstore-env
source bookstore-env/bin/activate
pip install -r requirements.txt
JWT トークンの生成
この例の Bookstore によって使用されているサービス間認証では、呼び出し側のサービスはサービス アカウントによってのみ認証されます。そのため、リクエストで送信する適切なトークンの作成は簡単です。生成されたトークンをさらに Google が(Google ID トークンを使用して)認証しなければならないという、もっと厳格なサービス間認証を要求することもできます。
この例では、用意されている Python スクリプトで、ダミーのユーザー ID とメールアドレスを使用して、前にダウンロードした JSON キーファイルからトークンを生成できます。
スクリプトを使用してトークンを生成するには:
JWT トークンを生成し、それを変数
$JWT_TOKEN
に割り当てます。JWT_TOKEN=$(python jwt_token_gen.py \ --file=[SERVICE_ACCOUNT_FILE] \ --audiences=[SERVICE_NAME] \ --issuer=[SERVICE-ACCOUNT-ID])
ここで
[SERVICE_ACCOUNT_FILE]
は、ダウンロードした、ユーザー サービス アカウントの JSON キーファイルです。[SERVICE_NAME]
は、更新したサービス構成を Endpoints にデプロイしたときに返された Bookstore サービスの名前です。[SERVICE-ACCOUNT-ID]
は、サービス アカウントを生成したときに取得した完全なユーザー サービス アカウント ID です。
認証された gRPC 呼び出しの実行
この最後のステップでは bookstore_client.py
を使用します。これは、チュートリアルで使用したのと同じクライアントです。認証された呼び出しを行う場合、クライアントはメソッドの呼び出しで JWT をメタデータとして渡します。
サンプルを実行するには:
kubectl get services
を使用して、デプロイされた Bookstore の外部 IP アドレスを取得します。#kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo 10.11.246.240 104.196.186.92 80/TCP 10d endpoints 10.11.243.168 104.196.210.50 80/TCP,8090/TCP 10d esp-grpc-bookstore 10.11.254.34 104.196.60.37 80/TCP 1d kubernetes 10.11.240.1 <none> 443/TCP 10d
この場合は
esp-grpc-bookstore
サービスであり、その外部 IP は104.196.60.37
です。IP アドレスを変数
EXTERNAL_IP
に割り当てます。EXTERNAL_IP=104.196.60.37
次のコマンドを実行して、Bookstore サービスからすべての本棚のリストを取得します。
python bookstore_client.py --port=80 --host=$EXTERNAL_IP --auth_token=$JWT_TOKEN
このサービスは、現在の Bookstore に存在するすべての本棚を返します。トークンを提供しない、または JWT を生成するときに正しくないサービス アカウント ID を指定するとコマンドは失敗するので、これでダブルチェックできます。