🌏

Croud Runで作成したWEBアプリをIAPで認証させる方法

2022/10/08に公開

はじめに

Croud Runで作成したWEBアプリは認証機能を持っていないのでIAPを有効にして認証させたい、
そんなユースケースを作りたくて構築してみました。

※2022年10月現在、本機能はプレビュー版のようです。
Cloud Run での IAP の有効化
https://cloud.google.com/iap/docs/enabling-cloud-run
手順もCloud Load BalancerやサーバーレスNEG(ネットワーク エンドポイント グループ)、OAuth2.0、IAPそしてCloud Runと多岐に渡っており、独自のドメインやSSL証明書も必要だったりして非常に複雑でした。

以下のサイトが良く纏まっていたので参考にしました。
https://hodo.dev/posts/post-30-gcp-cloudrun-iap/

前提条件・制限事項・準備するもの

  • 外部HTTP(S)ロードバランサーに設定するSSL証明書のため独自ドメインDNSのレコード設定が必要です。
  • 443通信である必要があります。
  • すべての外部リクエストは IAP 経由で承認される必要があります。
    制限事項他

https://cloud.google.com/iap/docs/enabling-cloud-run#known_limitations

システム構成

以下のような構成で構築します。
システム構成

必要な作業

必要な作業は主に以下の4つです。

  1. Cloud Runサービスのデプロイ
  2. IAP の設定
  3. 外部ロードバランサーの設定
  4. 許可したいユーザアカウントをIAPに追加

① Cloud Run サービスのデプロイ

コンソールにログインした状態でCloud Runのページを開き、Cloud Run サービスを作成します。
Cloud Runデプロイ1

今回はサンプルのWEBアプリケーションをデプロイするので、以下のように設定します。

  • 「既存のコンテナ イメージから 1 つのリビジョンをデプロイする」には「us-docker.pkg.dev/cloudrun/container/hello」を指定します。

  • サービス名は自動で「hello」になります。← 記憶しておいてください。

  • リージョンはどこでも構いませんが、今回の設定は「us-central1」とし、これを覚えておきます。

Ingress 設定

  • Ingressの設定で「内部トラフィックと Cloud Load Balancing からのトラフィックを許可する」にチェックを入れます。

  • 認証の設定では「認証が必要」にチェックを入れて作成ボタンを押します。

これでCloud Runによるサンプルアプリ「hello」が作成されました。

② IAPの設定

  • OAuth 同意画面の設定
    Cloud コンソールから 「APIとサービス」→ 「OAuth 同意画面」を開きます。

未設定の場合は以下のように設定してください。

OAuth同意画面の設定

「アプリ名」および「ユーザーサポートメール 」(アドレス)を入力します。ここにはアプリケーションの名前(任意)とユーザー自身の受信可能なメールアドレスか、Googleグループのアドレスを入力してください。

デベロッパーの連絡先情報

「デベロッパーの連絡先情報」にメールアドレスを入力します。

一度「保存して次へ」ボタンを押し、設定を保存して元の「OAuth同意画面の設定」画面に戻ります。
OAuth同意画面の設定2

「公開ステータス」を今回は「テスト」にします。

「ユーザーの種類」を「外部」にします。

「テストユーザー」の「ADD USERS」ボタンをクリックし、OAuth2.0で認証させる(Cloud RunのWEBアプリにアクセスする)対象のユーザーアカウントを設定します。

テストユーザー

  • OAuthの認証情報(クライアントIDとシークレット)の設定

Cloud コンソールから 「APIとサービス」→ 「認証情報」を開きます。
認証情報

画面上部「認証情報を作成」をクリックし「OAuthクライアントID」を選択します。

画面が遷移したら、「アプリケーションの種類」にて「ウェブアプリケーション」を選択します。「作成」をクリックすると、画面にクライアントIDとクライアントシークレットが生成され表示されます。OKを押してください。

作成したOAuth 2.0 クライアント ID をクリックすると、クライアントIDとクライアントシークレットが表示されるので、ここで確認することもできます。
クライアントIDとクライアントシークレット

  • 「承認済みのリダイレクト URI」に以下のフォーマットのリダイレクトURIを設定してください
    承認済みのリダイレクト URI

https://iap.googleapis.com/v1/oauth/clientIds/CLIENT_ID:handleRedirect

クライアントIDは以下のようなフォーマットです。

75641163784-some-random-number.apps.googleusercontent.com

「保存」をクリックします。以上でOAuth2.0の設定および認証情報の設定は完了です。

③ 外部ロードバランサーの設定

Cloud Runサービスがデプロイされ、IAPが有効になると、次のステップではNEG(Network Endpoint Group)を作成することになります。ネットワークエンドポイントグループ(NEG)は、バックエンドエンドポイントまたはサービスのグループを指定する設定オブジェクトです。完全なドキュメントはこちらで読むことができます。 ネットワークエンドポイントグループの概要

ここからは外部ロードバランサーの設定を、主にCloud Shellからgcloudコマンドを使って行っていきます。

まずはいくつか事前に変数を設定しておきます。

PROJECT_ID=[YOUR_PROJECT_ID]
REGION=[REGION_OF_CLOUD_RUN_DEPLOYED] <= (今回はus-central1)
CLIENT_ID=[YOUR_CLIENT_ID]
CLIENT_SECRET=[YOUR_CLIENT_ID]
CLOUD_RUN_SERVICE=[YOUR_CLOUD_RUN_SERVICE] <=(今回はhello)
  • NEGを作成
gcloud compute network-endpoint-groups create cloud-run-iap-neg \
    --project $PROJECT_ID \
    --region=$REGION \
    --network-endpoint-type=serverless  \
    --cloud-run-service=$CLOUD_RUN_SERVICE
  • バックエンドサービスを作成
gcloud compute backend-services create cloud-run-iap-backend \
    --load-balancing-scheme=EXTERNAL \
    --global \
    --iap=enabled,oauth2-client-id=$CLIENT_ID,oauth2-client-secret=$CLIENT_SECRET
  • バックエンドサービスにバックエンドとしてサーバーレスNEGを追加
gcloud compute backend-services add-backend cloud-run-iap-backend \
    --global \
    --network-endpoint-group=cloud-run-iap-neg \
    --network-endpoint-group-region=$REGION
  • url mapsを作成
gcloud compute url-maps create cloud-run-iap-url-map \
  --default-service cloud-run-iap-backend
  • 固定IPアドレスを予約します。
gcloud compute addresses create cloud-run-iap-ip \
    --network-tier=PREMIUM \
    --ip-version=IPV4 \
    --global

gcloud compute addresses list --filter cloud-run-iap-ip

次の変数をあなたのオリジナルのドメイン名で更新してください。例:test.example.com

DOMAIN_ADDRESS=[your-domain-address] <= 所有しているドメイン名を設定
  • 上記手順で取得した固定IPアドレスをDNSのAレコードに登録し、インターネット上でtest.example.com を名前解決した時に取得した固定IPアドレスが返ってくるように設定します。
  • SSL証明書の作成
    ここまでの手順でフロントエンド以外のロードバランサーの設定が済んでいるので、Cloudコンソールの「ネットワークサービス」→ 「ロードバランシング」の画面には「cloud-run-iap-url-map」という名前でロードバランサーができているはずです。(見えない場合は画面を一度リロードしてください)

ロードバランサーをクリックし、画面上部の「編集」をクリックしてください。
SSL証明書作成①

「フロントエンドの構成」をクリックすると、設定画面が開きますが、「プロトコル」の部分を「HTTPS (HTTPS/2を含む)」に選択すると、既存のSSLの証明書を選択するか、もしくは「新しい証明書を作成」という選択肢が表示されるので、「新しい証明書を作成」をクリックします。以下の画面が表示されます。

SSL証明書作成②

今回、証明書の名前は以降のgcloudコマンドで指定するため「cloud-run-iap-cert」としています。
「Google マネージドの証明書を作成する」にチェックを入れます。
「ドメイン」には独自のドメイン名を入力します。
「作成」をクリックするとGoogle マネージドのSSL証明書が作成されます。

  • https proxyを作成
gcloud compute target-https-proxies create cloud-run-iap-http-proxy \
    --ssl-certificates cloud-run-iap-cert \
    --url-map cloud-run-iap-url-map
  • グローバルな転送ルールを作成(フロントエンドの作成)
gcloud compute forwarding-rules create cloud-run-iap-forwarding-rule \
    --load-balancing-scheme=EXTERNAL \
    --network-tier=PREMIUM \
    --address=cloud-run-iap-ip \
    --global \
    --ports 443 \
    --target-https-proxy cloud-run-iap-http-proxy

SSL証明書の状態がプロビジョニングとなり、アクティブになるまで30分~1時間(最大24時間)ほど掛かります。以下のような状態になるまで待ちます。
証明書状態

  • IAPの動作確認

ここまでくれば9割完了です。ロードバランサーがすべてのコンポーネントをセットアップするまで少し時間をおいてから、期待通りに動作するかテストしてください。

https://独自ドメイン にアクセスすると、google のログインページ(OAuth2.0)にリダイレクトされるはずです。

ログインすると、以下のようなエラーになるはずです。
IAPエラー画面

このエラーはIAPの認証に拒否されたということなので動作として正しいです。

④ 許可したいユーザアカウントを追加

バックエンド・サービスにユーザーを追加する必要があります。許可したいユーザーアカウントをIAPの画面から追加しましょう。

  • Cloud コンソールから「セキュリティ」→ 「Identity-Aware Proxy」にアクセスします。
    既に「cloud-run-iap-backend」という名前のバックエンドサービスのIAPが有効になり、「OK」のステータスになっているはずです。
    IAPユーザ追加

  • 画面右ペインにあるペインから「プリンシパルを追加」のボタンをクリックします。
    プリンシパルを追加

  • アクセス許可したいユーザアカウントを追加し、ロールに「IAP-secured Web App User」を付与して、「保存」をクリックします。
    IAP-secured Web App Userロール付与

  • 設定したドメインURLにて再度ログインできることを確認
    少し待ってから、ページを更新してください。以下のようなログイン画面が表示されるはずです。
    Cloud Run Web APP画面

403 Forbidden "Your client does not have permission to get URL / from this server."というエラーについて

なぜCloud Runのパーミッションを使わず、IAPに認証ユーザーを追加するだけなのか言うと、答えはこうなるからです。
Cloud Run Permission Error

Cloud Runのパーミッションはログインへのリダイレクトを処理せず、ユーザーが必要なパーミッションを持っていない場合、連絡先情報を含む素敵なページを表示しません。笑

設定の削除

# delete the forwarding-rule aka frontend
gcloud -q compute forwarding-rules delete cloud-run-iap-forwarding-rule --global
# delete the http proxy
gcloud -q compute target-https-proxies delete cloud-run-iap-http-proxy
# delete the url map
gcloud -q compute url-maps delete cloud-run-iap-url-map
# delete the backend
gcloud -q compute backend-services delete cloud-run-iap-backend --global
# delete the NEG  
gcloud -q compute network-endpoint-groups delete cloud-run-iap-neg --region=$REGION
# delete the ssl certificate
gcloud -q compute ssl-certificates delete cloud-run-iap-cert
# delete the ip address
gcloud -q compute addresses delete cloud-run-iap-ip --global
# delete the cloud run service
gcloud -q run services delete cloud-run-iap --region $REGION

最後に

Cloud RunとIAPを組み合わせることで、最高のセキュリティで保護されたフルマネージドサーバーレスプラットフォームの恩恵を受けることができます。

Discussion