実際にラボを実施した際の記録を載せていきます。
学習の助けになったリンクや、後に見るための学習メモ、ちょっと迷った手順を書いていきます。
あと、コマンドも忘れたくないのでログしていきます。
- 学習の助けになったリンクは、「学習に役立つリンク」にまとめて書いてあります。
- 学習メモはアイコンをつけてます。
- 迷った手順は箇条書きでつらつら書いてます。
実際の手順については、Google Cloud Skills Boostのラボの手順を参照してください。
クエスト「Security & Identity Fundamentals」の5つめのラボです。
SkillBoostの始め方は記事「GCP スキルバッジをもらおう 1Google Cloud Skill Boostをはじめよう」をどうぞ。
この記事は「GCP スキルバッジをもらおう! 〜Security & Identity Fundamentals Advent Calendar 2021」の一部として公開しています。
25日にスキルバッジが獲得できるペースで公開していきます。
##ラボの情報
ラボの名前:ユーザー認証: Identity-Aware Proxy
所要時間:1時間 レベル:Fundamental 必要なクレジット:5
概要:
AppEngineにアプリを構築して、IAP(Identity-Aware Proxy)を使用してアクセスを制限したり、ユーザー情報を提供したりする。
Identity-Aware Proxy(IAP)とは?
- BeyondCorpセキュリティモデル(ゼロトラストっぽいやつ)に基づいた設計
- Google Cloud の外部にある HTTP ベースアプリにアクセスできます。
- アプリケーションに送信されたウェブ リクエストをインターセプトし、リクエストを送信したユーザーを Google の ID サービスを使用して認証し、認証されたユーザーからのリクエストのみを通過させます。
- さらに、リクエスト ヘッダーを変更して認証されたユーザーに関する情報を含めることができます。
IAPによって提供される情報
リクエストヘッダにアクセスしたユーザの情報が提供される
X-Goog-Authenticated-User-Email
:アクセスしているユーザのメールアドレス
X-Goog-Authenticated-User-ID
:アクセスしているユーザのID
X-Goog-IAP-JWT-Assertion
:アクセスしているユーザ検証用の署名データ
##学習に役立つリンク
参考URL:
Identity-Aware Proxy
IAP で保護されたリソースへのアクセスの管理
ユーザIDの取得
関連SDK:
jwt decode
##ラボの実施記録
###コードをダウンロードする
パブリックのバケットからサンプルコードをダウンロードして解凍する。
$gsutil cp gs://spls/gsp499/user-authentication-with-iap.zip .
$unzip user-authentication-with-iap.zip
$cd user-authentication-with-iap
###アプリケーションをデプロイして IAP で保護する
####アプリケーション コードを確認する。
ラボのステップごとに、フォルダにわけてコードが保存されている。
Editorを開いてちょっと確認してみる。
こんな感じ。
- main.py
アプリケーションコード。Flask ウェブ フレームワークを使用し、テンプレートの内容を利用してウェブリクエストに応答する。 - templates/index.html テンプレートファイル。
- templates/privacy.html 2 番目のテンプレート ファイルには、簡単なプライバシー ポリシーのサンプルが含まれています。
- requirements.txt アプリケーションが使用する Python ライブラリ(デフォルト以外)がすべてリストされています。
- app.yaml このアプリケーションが Python App Engine アプリケーションであることを Google Cloud に通知するファイル。
####AppEngineへデプロイする
gcloud app deploy
regionの選択、適当にアジアを選択しました
Please choose the region where you want your App Engine application located:
[1] asia-east1 (supports standard and flexible)
[2] asia-east2 (supports standard and flexible and search_api)
...
...
Please enter your numeric choice: 1
Continueを求められたらY
で、おそらくみなさん、必ず初回は失敗します。
同じコマンドをもう一度実行すればOKっす。
ERROR: (gcloud.app.deploy) NOT_FOUND: Unable to retrieve P4SA: [service-670719700473@gcp-gae-service.iam.gserviceaccount.com] from GAIA. Could be GAIA propagation delay or request from deleted apps.
deployしたアプリを確認します。
リンクをクリックすると、ブラウザタブが起動されて画面が見えます。
Hello World
と表示さればOK。
$gcloud app browse
Did not detect your browser. Go to this link to view your app:
https://<Project_id>.de.r.appspot.com
####IAPを使用してアクセスを制限する
クラウドコンソールで操作します。
ハンバーガー>Security>Identity-Aware Proxyを開いて、ラボの指示通りに設定、実行する。
CloudShellで、次のコマンドを実行して、Flex API を無効にする。
$gcloud services disable appengineflex.googleapis.com
App Engine には、さまざまなアプリケーション アーキテクチャ向けに最適化された標準の柔軟な環境があります。 現在、App Engine で IAP を有効にする場合、Flex API が有効になっていると、Google Cloud は Flex サービスアカウントを検索します。 Qwiklabs プロジェクトには、利便性を目的としてすでに有効になっている多数の API が付属しています。 ただし、これにより、サービスアカウントを作成せずに FlexAPI が有効になるという任意の状況が発生します。
CloudConsoleの[Identity-Aware Proxy]でIAPを有効にします。一覧の「IAP」列のボタンをスライドさせます。
Statusが緑になればOK。
IAPが有効になりました。
####IAP が有効になっていることをテストする
まだ、どのユーザーを許可するか設定をしていないので、この状態にアプリにアクセスをすると、拒否されます。
###ユーザー ID 情報へアクセスする
####AppEngineにデプロイする
こんどは、2つ目のアプリをデプロイします。
$cd ~/user-authentication-with-iap/2-HelloUser
$gcloud app deploy
####アプリケーション ファイルを調べる
構成は、1つ目のアプリと同じです。
main.py
に、ユーザー情報を取得する処理が加えられています。次の箇所。
user_email = request.headers.get('X-Goog-Authenticated-User-Email')
user_id = request.headers.get('X-Goog-Authenticated-User-ID')
X-Goog-Authenticated-User- ヘッダはIAP によって提供されている。
テンプレートファイルで値を表示できるように渡している。
page = render_template('index.html', email=user_email, id=user_id)
テンプレートファイルindex.html
の表示箇所。
Hello, {{ email }}! Your persistent ID is {{ id }}.
####更新されたIAPをテストする
gcloud app browse
ブラウザでリンクを開いて、更新したAPIをテストする。
ユーザー情報、Emailアドレスが表示されていればOK。
####IAPを無効にする
今度は、IAPを無効にした状態でアプリを確認すると、アクセスはできるけどユーザー情報が表示されなくなっていることがわかる。
###暗号検証を使用する
デジタル署名を検証してIDが有効かどうかユーザーを検証する方法をためす。
IAP によって追加された X-Goog-IAP-JWT-Assertion
リクエストヘッダーを使用する。
####App Engineをデプロイする
3番目のアプリをデプロイする。
####アプリケーションファイルを確認する
構成は1つめ、2つめとおなじ。
auth.py
ファイルが追加されている。
暗号で署名された ID 情報を取得して検証するためのuser()
メソッドを記述している。
user()
メソッドの内容:
assertion
に、X-Goog-IAP-JWT-Assertion
ヘッダーで取得した署名データを格納して、検証およびデコードする。
検証では、署名されたデータを確認し、Google 提供の公開鍵を使用。
ヘルパー関数の keys() と audience() がそれらの値を収集して返す。
検証済みのメールアドレスと一意の ID 値(サブスクライバーの場合は、sub 標準フィールドに指定)の 2 つのデータ、これらの値を戻す。
def user():
assertion = request.headers.get('X-Goog-IAP-JWT-Assertion')
if assertion is None:
return None, None
info = jwt.decode(
assertion,
keys(),
algorithms=['ES256'],
audience=audience()
)
return info['email'], info['sub']
main.py
とindex.html
はuser()
関数の結果を表示するように変更している。
####暗号検証をテストする
3つ目のアプリをデプロイしてブラウザで確認する。
IAP無効な状態のままで、一度表示を確認して、
IAPを有効にして、再度表示を確認する。
「Hello Verified User」画面でアカウントとemailアドレスが表示されていればOK。
##お疲れさまでした
これでラボの手順は終了。
右上のスコア表示が「100/100」になっていることを確認して、「ラボを終了」を押します。