IAPで保護されたリソースの認証をスクリプトで突破する
IAP認証とは
Cloud Identity Aware Proxyとは、認証機能を挟むことができる仕組みになります。
Googleのドキュメントによると、
IAP とは、ウェブサイトへのリクエストをインターセプトし、リクエストを送信したユーザーを認証して、認証されたユーザーにのみサイトへのアクセスを許可する、という一連の処理を行うサービスです
大体の場合は、ブラウザからアクセスして認証画面が表示され、認証を行うという感じだと思います
実際に表示される画面は下記のような感じになります。
上記をブラウザではなく、サーバーを通してプログラムから行いたい場合があります
今回やること
phpスクリプトを通して、IAP認証があるGAEのアプリケーションを叩きます。
今回は、terraformを使っての管理は行いません。GCP周りはコンソールを通して操作します。
作成開始
サンプルアプリの作成
Cloud Shellで、サンプルのリポジトリをcloneしてきて、対象のディレクトリに移動して、アプリをデプロイします
git clone https://github.com/GoogleCloudPlatform/golang-samples.git
cd golang-samples/appengine/go11x/helloworld
gcloud app deploy
生成されたURLにアクセスすると、「hello world」と表示されていると思います。
IAP認証をアプリにかける
IAPのOAuth同意確認画面を作成します
下記を入力していきます。(今回の場合は書き込む内容は割と何でも良いはず)
その後、IAP認証をONにして
「ADD PRINCIPAL」ボタンを押して、有効なユーザーを追加します。
その結果、認証画面を通して、アクセスできるようになるはずです
プログラムでIAP認証を行う
プログラムでIAP認証を行うためには
サービスアカウントキーにIAMで権限を付けた上で
- サービスアカウントキー
- cliend_id
の2つが必要になります。
サービスアカウントキーにIAP認証のための権限を付ける
まずは、「ADD PRINCIPAL」ボタンを押して、サービスアカウントに対して権限を付けます
サービスアカウントキーの取得
「IAMと管理 > サービスアカウント > キー」からサービスアカウントキーを追加し、jsonファイルをローカルに取得してきます
cliend_idの取得
「セキュリティ > identity Aware Proxy 」から「OAuthの構成に移動」を選んで、
そのさきでクライアントidをメモる
スクリプト
クライアントidとサービスアカウントキーの両方を指定したバージョンがネットを探してもなかったので、ライブラリ内を読んで作成したものが下記になります。
php iap_request.php
で実行したら、「hello world」という結果が帰ってくるはずです
<?php
require('vendor/autoload.php');
# Imports Auth libraries and Guzzle HTTP libraries.
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\Middleware\ScopedAccessTokenMiddleware;
use Google\Auth\Middleware\AuthTokenMiddleware;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
$credentialsFile = 'サービスアカウントのクレデンシャルjsonへのパス';
$url = 'GAEアプリのURL';
$clientId = '取得したClient id';
$serviceAccountCredentials = json_decode(file_get_contents($credentialsPath), true);
$creds = new ServiceAccountCredentials(null, $serviceAccountCredentials, null, $clientId);
// create middleware
$middleware = new AuthTokenMiddleware($creds);
$stack = HandlerStack::create();
$stack->push($middleware);
// create the HTTP client
$client = new Client([
'handler' => $stack,
'base_uri' => 'https://www.googleapis.com',
'auth' => 'google_auth' // authorize all requests
]);
// make the request
$response = $client->get($url);
echo $response->getBody() . "\n";
今回のコード
下記リポジトリ置いておきました
Discussion