目標
IAP を使用することにより、App Engine アプリのユーザーに自分自身を認証するように要求する。
アプリでユーザーの ID にアクセスして、現在のユーザーの認証済みメールアドレスを表示する。
費用
このドキュメントでは、課金対象である次のコンポーネントを使用します。 Google Cloud
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- アカウントにログインします Google Cloud を初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。 Google Cloud新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init
背景
このチュートリアルでは、IAP を使用してユーザーを認証します。これは、いくつかのアプローチのうちの 1 つにすぎません。ユーザーのさまざまな認証方法の詳細については、認証のコンセプトセクションをご覧ください。
Hello user-email-address アプリ
このチュートリアル用のアプリは、最小の Hello world App Engine アプリで、「Hello world」の代わりに「Hello user-email-address」を表示する特別な機能を備えています。ここで、user-email-address は認証済みユーザーのメールアドレスです。
この機能は、IAP がアプリに渡す各ウェブ リクエストに追加する認証情報を調べることで可能になります。アプリに届くリクエストには 3 つの新しいリクエスト ヘッダーが追加されます。最初の 2 つのヘッダーは、ユーザーの識別に使用できる書式なしテキスト文字列です。3 つ目のヘッダーは、同じ情報を含む暗号署名付きオブジェクトです。
X-Goog-Authenticated-User-Email: ユーザーのメールアドレスでユーザーが識別されます。アプリで回避できる場合は、個人情報を保存しないようにしてください。このアプリはデータを保存しません。ユーザーにエコーバックするだけです。X-Goog-Authenticated-User-Id: Google が割り当てたこのユーザー ID は、ユーザーに関する情報は表示しませんが、ログインしているユーザーが過去に表示されたユーザーと同じであることをアプリが認識できるようにします。X-Goog-Iap-Jwt-Assertion: アプリは、インターネット ウェブ リクエスト以外に、IAP を迂回してきた他のクラウドアプリからのウェブ リクエストを受け入れるように構成できます。 Google Cloud アプリがこのように構成されている場合は、このようなリクエストのヘッダーが偽造されている可能性があります。 上記のいずれかの書式なしテキスト ヘッダーを使用する代わりに、この暗号署名付きヘッダーを使用して、情報が Google から提供されたものであることを確認できます。ユーザーのメールアドレスと永続的なユーザー ID の両方をこの署名付きヘッダーの一部として使用できます。
アプリが、インターネット ウェブ リクエストのみを受け入れ、アプリに対する IAP サービスを無効にできないように構成されている場合は、一意のユーザー ID を取得するコードは 1 行で済みます。
$userId = getallheaders()['X-Goog-Authenticated-User-Id'] ?? null;
ただし、回復性の高いアプリは予期せぬ構成や環境問題などの障害を想定しておく必要があるため、代わりに、暗号署名付きヘッダーを使用して確認する関数を作成することをおすすめします。 ヘッダーの署名は偽造できないため、検証時に、識別を返すのに使用できます。
ソースコードを作成する
テキスト エディタを使用して、
index.phpという名前のファイルを作成し、次のコードを貼り付けます。この
index.phpファイルの詳細については、このチュートリアルの後半の コードについて セクションで説明します。composer.jsonという名前の別のファイルを作成し、次のコードを貼り付けます。composer.jsonファイルでは、App Engine で読み込む必要のある PHP ライブラリが一覧表示されます。firebase/php-jwtは、JWT のチェックおよびデコード機能を提供します。guzzle/httpは、ウェブサイトからデータを取得するための HTTP クライアントです。
app.yamlという名前のファイルを作成し、次のテキストを入力します。app.yamlファイルは、コードが必要とする言語環境を App Engine に指示します。
コードの説明
このセクションでは、index.php 内のコードの機能について説明します。アプリを実行するだけの場合は、アプリのデプロイ セクションまでスキップできます。
次のコードが index.php ファイルに格納されています。ホームページへの
リクエストが
アプリによって受信された場合は、/ のスイッチケースが呼び出されます。HTTP GET
スイッチ ステートメントは、IAP が受信リクエストから追加した JWT アサーション ヘッダー値を取得し、その暗号署名付き値を検証する関数を呼び出します。返される最初の値(メール)は、作成されて返される最小ウェブページで使用されます。
validate_assertion 関数は、google/auth ライブラリを使用して、アサーションが適切に署名されていることを確認し、アサーションからペイロード情報を抽出します。アサーションをデコードできない場合は、この関数は例外をスローします。成功すると、この関数は認証済みユーザーのメールアドレスと永続的な一意の ID を返します。
JWT アサーションを検証するには、アサーションに署名したエンティティ(この場合は Google)の公開鍵証明書と、アサーションの対象オーディエンスを把握している必要があります。App Engine アプリの場合、オーディエンスは プロジェクト識別情報を含む文字列です。 Google Cloud この関数は、それらの証明書とその前の関数からのオーディエンス文字列を取得します。
自分で Google Cloud プロジェクトの数値 ID と名前を検索して、ソースコードに含めることもできますが、代わりに、audience 関数が App Engine アプリで利用可能な標準のメタデータ サービスを照会することによってこの処理を行います。
App Engine のメタデータ サービス(および他の
Google Cloud コンピューティング サービス用の類似のメタデータ サービス)は、外観がウェブサイトに似ており、
標準のウェブクエリによって照会されます。ただし、実際には、外部サイトではなく、実行中のアプリに関する要求された情報を返す内部機能であるため、https リクエストの代わりに http リクエストを使用しても安全です。これは、JWT アサーションの対象オーディエンスを定義するために必要な現在の Google Cloud 識別子を取得するために使用されます。
アプリのデプロイ
これで、アプリをデプロイして、次いで Cloud IAP でユーザーが認証しないとユーザーがアプリにアクセスできないようにできます。
ターミナル ウィンドウで、
app.yamlファイルが格納されたディレクトリに移動して、アプリを App Engine にデプロイします。gcloud app deployプロンプトが表示されたら、最寄のリージョンを選択します。
デプロイ操作を続行するかどうかを尋ねられたら、
Yと入力します。数分以内に、アプリがインターネット上に公開されます。
次のようにしてアプリを表示します。
gcloud app browse出力で、
web-site-url(アプリのウェブアドレス)をコピーします。ブラウザ ウィンドウで、
web-site-urlを貼り付けてアプリを開きます。IAP をまだ使用していないのでメールが表示されないため、ユーザー情報がアプリに送信されません。
IAP を有効にする
これで App Engine インスタンスが存在するようになり、IAP を使用して保護できます。
コンソールで、[Identity-Aware Proxy] ページに移動します。 Google Cloud
今回はこのプロジェクト用の認証オプションを初めて有効にしたため、IAP を使用するには OAuth 同意画面を構成する必要があることを示すメッセージが表示されます。
[同意画面を構成] をクリックします。
[認証情報] ページの [OAuth 同意画面] タブで、次のフィールドに値を入力します。
アカウントが Google Workspace の組織にある場合は、[外部] を選択して [作成] をクリックします。開始すると、アプリは明示的に許可されたユーザーのみが利用できます。
[アプリケーション名] フィールドに、
IAP Exampleと入力します。[サポートメール] フィールドに、メールアドレスを入力します。
[承認済みドメイン] フィールドに、アプリの URL のホスト名部分(
iap-example-999999.uc.r.appspot.comなど)を入力します。フィールドにホスト名を入力したら、Enterキーを押します。[アプリケーション ホームページ リンク] フィールドに、アプリの URL(
https://iap-example-999999.uc.r.appspot.com/など)を入力します。[Application privacy policy line] フィールドでは、テスト用にホームページ リンクと同じ URL を使用します。
[保存] をクリックします。認証情報の作成が要求されたら、ウィンドウを閉じます。
コンソールで、[Identity-Aware Proxy] ページに移動します。 Google Cloud
ページを更新するには、[Refresh](更新)をクリックします。refreshページに、保護可能なリソースのリストが表示されます。
[IAP] 列でクリックしてアプリの IAP をオンにします。
ブラウザで、再度
web-site-urlにアクセスします。ウェブページの代わりに、自分を認証するためのログイン画面が表示されます。ログインしようとすると、アプリにアクセス可能なユーザーのリストが IAP にないため、アクセスが拒否されます。
アプリに承認済みユーザーを追加する
コンソールで、[Identity-Aware Proxy] ページに移動します。 Google Cloud
App Engine アプリのチェックボックスをオンにしてから、[プリンシパルを追加] をクリックします。
allAuthenticatedUsersと入力してから、[Cloud IAP/IAP で保護されたウェブアプリ ユーザー] 役割を選択します。[保存] をクリックします。
これで、Google で認証可能なすべてのユーザーがアプリにアクセスできます。必要に応じて、1 人または複数のユーザーやグループをプリンシパルとして追加するだけで、さらにアクセスを制限できます。
Gmail または Google Workspace のメールアドレス
Google グループ メールアドレス
Google Workspaceのドメイン名
アプリにアクセスする
ブラウザで、
web-site-urlにアクセスします。ページを更新するには、[更新] refresh 更新をクリックします。
ログイン画面で、Google 認証情報を使用してログインします。
ページに、メールアドレスが記載された「Hello
user-email-address」ページが表示されます。以前と同じページが表示される場合は、IAP を有効にしたブラウザで新しいリクエストが完全に更新されない問題が発生している可能性があります。すべてのブラウザ ウィンドウを閉じてから、もう一度開いて、やり直してください。
認証のコンセプト
アプリが、そのユーザーを認証し、承認されたユーザーのみにアクセスを制限可能な方法がいくつかあります。次のセクションで、一般的な認証方法をアプリの負荷が高い順に一覧表示します。
| オプション | メリット | デメリット |
|---|---|---|
| アプリ認証 |
|
|
| OAuth2 |
|
|
| IAP |
|
|
アプリ管理認証
この方法では、アプリがユーザー認証のすべての側面を独自に管理します。アプリは、ユーザー認証情報の独自のデータベースを維持してユーザー セッションを管理し、ユーザー アカウントとパスワードの管理、ユーザー認証情報のチェック、認証されたログインごとのユーザー セッションの発行、チェック、更新を行う必要があります。次の図は、アプリ管理認証方法を示しています。
図に示すように、ユーザーがログインすると、アプリがそのユーザーのセッションに関する情報を作成して維持します。ユーザーがアプリにリクエストを発行する場合は、そのリクエストにアプリが検証するセッション情報が含まれている必要があります。
このアプローチの主なメリットは、自己完結型であることと、アプリの制御下で行われることです。アプリをインターネット上で使用可能にする必要さえありません。主なデメリットは、アプリがすべてのアカウント管理機能を提供し、すべての機密性の高い認証情報データを保護する必要があることです。
OAuth2 を使用した外部認証
アプリ内ですべてを処理する代わりに、Google などの外部の ID サービスを使用して、すべてのアカウント情報と機能を処理し、機密性の高い認証情報を保護することをおすすめします。ユーザーがアプリにログインしようとすると、リクエストが ID サービスにリダイレクトされ、そこでユーザーが認証されてから、必要な認証情報と一緒にリクエストがアプリに返されます。詳しくは、Using OAuth 2.0 for Web Server Applications(英語)をご覧ください。
次の図は、OAuth2 方式を使用した外部認証を示しています。
図のフローは、ユーザーがアプリにアクセスするためのリクエストを送信するところから始まります。直接応答する代わりに、アプリは、ユーザーのブラウザを Google の Identity Platform にリダイレクトします。そこで、Google にログインするためのページが表示されます。ログインに成功すると、ユーザーのブラウザがアプリに戻されます。このリクエストには、認証されたユーザーに関してアプリが検索可能な情報が含まれており、アプリはユーザーに応答できます。
この方法には、アプリにとっての多くのメリットがあります。アプリがすべてのアカウント管理機能とリスクを外部サービスに委任することで、アプリを変更せずにログインとアカウント セキュリティを向上させることができます。ただし、上の図に示すように、この方法を使用するには、アプリからインターネットにアクセスできる必要があります。また、アプリには、ユーザーの認証後にセッションを管理する責任があります。
Identity-Aware Proxy
このチュートリアルで扱う 3 つ目のアプローチは、IAP を使用して、認証とアプリに対するなんらかの変更を伴うセッション管理をすべて処理する方法です。IAP は、アプリへのすべてのウェブ リクエストを傍受して、認証されていないリクエストをブロックし、それ以外のリクエストはリクエストごとにユーザー ID データを追加してアプリに渡します。
リクエストの処理を次の図に示します。
ユーザーからの要求は、IAP によって傍受され、認証されていない要求がブロックされます。認証されたユーザーが許可されたユーザーのリストに含まれている場合は、認証されたリクエストがアプリに渡されます。IAP を介して渡されたリクエストには、要求を行ったユーザーを識別するヘッダーが追加されます。
アプリは、ユーザー アカウントやセッション情報を処理する必要がなくなります。ユーザーの一意の識別子を知る必要があるオペレーションでは、受信ウェブ リクエストから直接取得できます。ただし、App Engine やロードバランサなど、IAP をサポートするコンピューティング サービスでのみ使用できます。ローカル開発マシンで IAP を使用することはできません。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
- コンソールで [**リソースの管理**] ページに移動します。 Google Cloud
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、 [Shut down] をクリックしてプロジェクトを削除します。