:wq!

Google Cloud Identity-Aware Proxy(Cloud IAP)でWebアプリに認証を追加する

ども、takiponeです。
先日サンフランシスコで開催されたGoogle Cloud Next '17ではGCP(Google Cloud Platform)の多くの新機能が発表されました。その中で個人的にツボだったのがCloud Identity-Aware Proxy(以下Cloud IAP)でした。既にベータ版として触ることができたので、その様子をレポートします。

Cloud Identity-Aware Proxy(IAP:ID認証プロキシ)とは

Cloud IAPは、Googleアカウントの認証機能を提供するリバースプロキシサービスです。OSSのgateのas a Service版という説明が近いと思います。Google認証に対応するIDaaSと比べてOpenID/OAuth2のフローを意識する必要がないため、既存のWebアプリケーションやWeb APIに手軽に組み込むことができます。

図ではプロキシ先がERP/CRMとなっていますが、以下のサービスをサポートします。

  • Google App Engine(GAE)
  • Google Compute Engine(GCE)
  • Google Container Engine(GKE)

GCEおよびGKEでは、HTTPSロードバランサのオプションとして動作します。

検証環境

今回は以下の構成で試してみました。

まずはVMインスタンスでWebアプリを起動、インスタンスグループとHTTPSロードバランサを作成、DNSをロードバランサに向けておいて、Webブラウザでアクセスします。

リクエストヘッダをダンプした、シンプルなレスポンスが表示されます。

Cloud IAPのセットアップ

それでは、HTTPロードバランサでCloud IAPオプションを有効にします。GCP Webコンソール画面では、[IAMと管理] - [ID認証プロキシ]を選択します。

中央のペインにある「ID認証プロキシ」にCloud IAPの対象リソースがリストされます。ロードバランサ単位ではなくバックエンドサービス単位なのがポイントで、画像など公開データをホストするバックエンドサービスはOFF、HTMLやJSONなど制限したいデータをホストするバックエンドサービスでONにするといった使い分けができそうです。

ロードバランサの既定の設定では、スクリーンショットにあるように[設定]列がバリデーションでエラー(赤丸のエクスクラメーションマーク)になりました。[ファイヤーウォール]のリンクをクリックすると、以下のダイアログが表示されます。

どうやらロードバランサを経由せずにVMインスタンスの80番ポートに直接アクセスできる状態がダメなようで、以下のようにdefault-allow-httpルールのソースIP範囲をロードバランサのIPに絞ることで解消できました(VMインスタンスのタグを変更し他のファイヤーウォールルールが適用されるように変更しましたが、エラーは解消されませんでした。ちょっとバグっぽい動きかな)。

気を取り直して、リソースの[IAP]のスイッチをONにします。

ドメイン名入力のダイアログが表示されるので、HTTPSロードバランサに向いているドメイン名を入力し、[有効にする]をクリックします。

続いて、アクセスを許可するGoogleアカウントを指定します。画面右側の[Access]ペインの「追加」をクリックします。

メンバーの追加ダイアログが開きます。どんな指定ができるかは[?]マークにマウスオーバーすると以下のように表示されます。

今回はGmailのメールアドレスを入力し、[追加]で登録しました。

動作確認

再度Webブラウザでアクセスしてみると...

先ほどのレスポンス表示ではなく、見慣れたGoogleアカウントの認証画面にリダイレクトしました。先ほど指定したメールアドレス、パスワードを順に入力し、認証が完了すると...

先ほどと同じ、リクエストヘッダを含む、レスポンスが表示されました。正しく認証機能が動作しました。認証なしのときに加えてHTTPロードバランサが以下のヘッダを追加しています。

  • X-Goog-Authenticated-User-Email : 認証したメールアドレス
  • X-Goog-Authenticated-User-ID : 認証したGoogleアカウントID
  • X-Goog-Authenticated-User-JWT : JWT署名付きトークン

これらはバックエンドのWebアプリで活用できそうですね。Basic認証の代替として、X-Goog-Authenticated-User-EmailをWebサーバーのカスタムログに書き込むとか良さそうです。

JWT署名付きトークンの検証

Cloud IAPが付与するJWT署名付きトークンを検証してみました。この辺りはドキュメントに解説があります。

まずは、https://jwt.io/ のデバッガにトークンを貼り付けて紐解いてみます。

ペイロードに先ほどのメールアドレスのほか、タイムスタンプなどが含まれているのが分かります。正当性を検証するために、公開鍵を入手します。Googleが公開する鍵は、以下のURLでJSON形式の3種類があります。

$ curl https://www.gstatic.com/iap/verify/public_key
{
   "1aDm7w" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4rtreuHTI2mgFh63My3FgpR4w5tA\nKlLSqdu5UlMKSMhX7OXyqUOKlhdCJmCGcvJyCeC9c+HooIJClaUiJmYi8A==\n-----END PUBLIC KEY-----\n",
   "Ci2qZQ" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+nR06xvnL4hanbFlNYKXrmfWJ1oX\nuGkgBorc3neV769qFdRWQJphHH4u8nYiNmYTcfAq+YCuBTf+3H37ZxXCeQ==\n-----END PUBLIC KEY-----\n",
   "N2_6BA" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuGY5UNVDiwDt5Z7IPwvPM2Oi2J25\noFvgqEJngZk57YFLpWz8+2sNRnagAjw40x3kuzKu9I60xEj1Ba/XLJYcFA==\n-----END PUBLIC KEY-----\n"
}
$

どの鍵が対応するかは、ヘッダのkidで指定されます。今回はN2_6BAだったので、以下のコマンドラインで公開鍵を取得します。

$ curl -s https://www.gstatic.com/iap/verify/public_key | jq -r '.["N2_6BA"]'
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuGY5UNVDiwDt5Z7IPwvPM2Oi2J25
oFvgqEJngZk57YFLpWz8+2sNRnagAjw40x3kuzKu9I60xEj1Ba/XLJYcFA==
-----END PUBLIC KEY-----
$

これをデバッガに貼り付けると...

検証が通りました!バックエンドのWebアプリケーションで署名付きトークンを検証することで、Cloud IAPが付与した認証情報の正当性が確認できます。

まとめ

Googleの認証機能を追加できるCloud IAPの様子をご紹介しました。既存のWebアプリケーションに認証機能を追加する、良いサービスだと思います。

AWSにもCognite User Poolと連動する認証プロキシサービスが欲しいところです(^^

参考URL