1. 簡介
驗證網頁應用程式的使用者通常是必要的,而且通常需要在應用程式中進行特殊程式設計。就 Google Cloud Platform 應用程式而言,您可以將這些責任交給 Identity-Aware Proxy 服務。若只需要限制特定使用者的存取權,則無須對應用程式進行任何變更。如果應用程式需要知道使用者的身分 (例如為了將使用者偏好保留於伺服器端),則 Identity-Aware Proxy 可運用最少的應用程式程式碼提供這項資訊。
什麼是 Identity-Aware Proxy?
Identity-Aware Proxy (IAP) 是一項 Google Cloud Platform 服務,可攔截傳送至應用程式的網頁要求、透過 Google Identity 服務驗證提出要求的使用者,並且只有在要求來自您授權的使用者時才會通過。此外,這項功能還能修改要求標頭,加入已驗證使用者相關資訊。
本程式碼研究室將引導您建立自己的應用程式、限制存取應用程式,以及透過 IAP 取得使用者身分。
建構目標
在本程式碼研究室中,您會使用 Google App Engine 建構極少量的網頁應用程式,接著探索各種使用 Identity-Aware Proxy 限制應用程式存取權的方式,並向應用程式提供使用者身分資訊。您的應用程式將會:
|
課程內容
- 如何使用 Python 3.7 編寫及部署簡單的 App Engine 應用程式
- 如何啟用和停用 IAP 以限制應用程式存取權
- 如何透過 IAP 取得使用者身分資訊並提供給應用程式
- 如何以加密編譯的方式驗證 IAP 提供的資訊,防範假冒行為
軟硬體需求
- 使用新型網路瀏覽器,例如 Chrome。
- 具備 Python 程式設計語言的基本知識
本程式碼研究室著重於 Google App Engine 和 IAP。我們不會對與本主題無關的概念和程式碼多做介紹,但會事先準備好這些程式碼區塊,屆時您只要複製及貼上即可。
2. 開始設定
您將在 Cloud Shell 指令列環境中操作。首先,開啟該環境並擷取程式碼範例。
啟動控制台和 Cloud Shell
按一下研究室頁面左上方的「Open Google Console」按鈕。您必須使用該按鈕下方顯示的使用者名稱與密碼登入。 |
系統會在 Cloud Shell 中為您建立和開啟的專案執行本程式碼研究室中的所有指令。按一下控制台頁面標頭右側的「啟用 Cloud Shell」圖示,開啟 Cloud Shell。您可以在頁面的下半部輸入並執行指令。指令可以在您的電腦上執行,但您必須先安裝及設定必要的開發軟體。Cloud Shell 已有您需要的所有軟體工具。 |
下載程式碼
點選 Cloud Shell 中的指令列區域,即可使用指令。從 GitHub 擷取程式碼,然後變更為程式碼資料夾:
git clone https://github.com/googlecodelabs/user-authentication-with-iap.git
cd user-authentication-with-iap
這個資料夾包含本程式碼研究室每個步驟的子資料夾。您必須切換至正確的資料夾才能執行每個步驟。
3. 步驟 1 - 部署應用程式並使用 IAP 保護應用程式
這是以 Python 3.7 編寫的 App Engine Standard 應用程式,這個應用程式只會顯示「Hello, World」歡迎頁面。我們會部署並測試應用程式,然後使用 IAP 限制相關存取權。
查看應用程式程式碼
從主要專案資料夾變更為包含這個步驟程式碼的 1-HelloWorld
子資料夾。
cd 1-HelloWorld
應用程式程式碼位於 main.py
檔案中。會使用 Flask 網路架構,使用範本內容回應網路要求。這個範本檔案位於 templates/index.html
,在這個步驟中,只有純 HTML 檔案。第二個範本檔案包含 templates/privacy.html
中的基本隱私權政策範例。
還有兩個檔案:requirements.txt
會列出應用程式使用的所有非預設 Python 程式庫,app.yaml
則會告知 Google Cloud Platform 是否為 Python 3.7 App Engine 應用程式。
您可以使用 cat 指令在殼層中列出每個檔案,如下所示:
cat main.py
或者,您也可以按一下 Cloud Shell 視窗右上角的鉛筆圖示,開啟 Cloud Shell 程式碼編輯器,然後檢查程式碼。
在這個步驟中,您不需要變更任何檔案。
部署至 App Engine
現在,將應用程式部署至 Python 3.7 適用的 App Engine 標準環境
gcloud app deploy
系統可能會要求您選擇要部署的區域。如果附近顯示「支援標準」字樣,請選取附近商家。當系統詢問是否要繼續進行時,請輸入 Y
表示「是」。
部署應該會在幾分鐘內完成,屆時您將會看到可透過 gcloud app browse
查看應用程式的訊息。輸入該指令。如果瀏覽器沒有開啟新分頁,請按一下顯示的連結以在新分頁中開啟,或視需要將分頁複製到手動開啟的新分頁。由於是首次執行該應用程式,啟動雲端執行個體時需要幾秒鐘時間才會顯示,接著您應該會看到以下視窗。
您可以在任何連線至網際網路的電腦上開啟同一個網址,查看該網頁。存取權尚未受到限制。
透過 IAP 限制存取權
在 Cloud 控制台視窗中,依序點選頁面左上方的「選單」圖示 >「安全性」,然後點選「Identity-Aware Proxy」。 | |
由於這是您第一次為這項專案啟用驗證選項,因此系統會顯示訊息,請您先設定 OAuth 同意畫面,才能使用 IAP。 | |
按一下「設定同意畫面」按鈕。系統隨即會開啟新分頁,讓您設定同意畫面。 |
在所需欄位中填入適當的值:
應用程式名稱 | 應用程式內購範例 |
支援服務電子郵件地址 | 您的電子郵件地址。系統可能已為你填入內容 |
已授權網域 | 應用程式網址的主機名稱部分,例如iap-example-999999.appspot.com。您可以在先前開啟的 Hello World 網頁的網址列中查看這項資訊。請勿加入該網址的開頭 |
應用程式首頁連結 | 您用來瀏覽應用程式的網址 |
應用程式隱私權政策連結 | 應用程式中的隱私權頁面連結,就是在結尾加上 /privacy 的首頁連結 |
按一下「儲存」。系統會提示您建立憑證。您不需要為本程式碼研究室建立憑證,只要關閉這個瀏覽器分頁即可。
返回 Identity-Aware Proxy 頁面並重新整理。現在,您應該會看到可保護的資源清單。在「App Engine 應用程式」資料列中,按一下「IAP」欄中的切換鈕以啟用 IAP。 | |
您會看見將受 IAP 保護的網域名稱。按一下「開啟」。 | |
現在,請開啟瀏覽器分頁,然後前往應用程式的網址。系統會顯示「使用 Google 帳戶登入」畫面,您必須登入才能存取應用程式。 | |
請使用 Google 或 G Suite 帳戶登入。畫面會顯示「拒絕存取」。 |
您已成功使用 IAP 保護應用程式,但尚未指示 IAP 哪些帳戶有存取權。
返回控制台的「Identity-Aware Proxy」頁面,勾選 App Engine 應用程式旁邊的核取方塊,然後查看頁面右側的側欄。 | |
您必須將允許存取的電子郵件地址 (或 Google 群組地址或 G Suite 網域名稱) 新增為成員。按一下新增成員。輸入您的電子郵件地址,然後選擇要指派給該地址的 Cloud IAP/IAP 保護網頁應用程式使用者角色。您可以使用同樣的方式輸入更多地址或 G Suite 網域。 |
按一下「儲存」。系統隨即會在視窗底部顯示「已更新政策」訊息。
返回應用程式,然後重新載入頁面。您現在應會看見網頁應用程式,因為您已經透過授權的使用者登入。不過,您仍然可能看到「您沒有存取權」因為 IAP 可能不會重新檢查您的授權。在這種情況下,請執行下列步驟:
- 開啟網路瀏覽器並前往首頁網址,並在網址結尾加上
/_gcp_iap/clear_login_cookie
,例如:https://iap-example-999999.appspot.com/_gcp_iap/clear_login_cookie
。 - 您會看到新的「使用 Google 帳戶登入」畫面,當中顯示您的帳戶。請不要點選該帳戶,而是點選「使用其他帳戶」,然後重新輸入憑證。
- 這些步驟會使 IAP 重新確認存取權限,您現在應該可以看到應用程式的主畫面。
如果您可以使用其他瀏覽器,或是在瀏覽器中使用無痕模式,並且擁有其他有效的 Gmail 或 G Suite 帳戶,您就可以使用該瀏覽器前往您的應用程式頁面,然後使用其他帳戶登入。由於該帳戶尚未獲得授權,因此會顯示「您沒有存取權」畫面,而不是應用程式頁面。
4. 步驟 2:存取使用者身分資訊
應用程式受到 IAP 保護後,就能使用 IAP 在網頁要求標頭中提供的身分資訊。在這個步驟中,應用程式將取得已登入使用者的電子郵件地址,以及 Google Identity 服務指派給該使用者的永久專屬使用者 ID。系統會在歡迎頁面向使用者顯示這項資料。
此為步驟 2,最後一個步驟則是在 iap-codelab/1-HelloWorld
資料夾中開啟 Cloud Shell。變更為用來執行這個步驟的資料夾:
cd ~/iap-codelab/2-HelloUser
部署至 App Engine
由於部署作業需要幾分鐘才能完成,請先將應用程式部署至 Python 3.7 適用的 App Engine 標準環境:
gcloud app deploy
當系統詢問您是否要繼續時,請輸入 Y 表示「是」。部署應該會在幾分鐘內完成。等待過程中,您可以按照下方說明檢查應用程式檔案。
部署作業準備就緒時,您會收到訊息,您可以使用 gcloud app browse
查看應用程式。輸入該指令。如果瀏覽器未開啟新分頁,請將顯示的連結複製到新分頁正常開啟。您應該會看到類似以下頁面:
系統可能需要幾分鐘,才能將先前的應用程式版本替換為新版本。請視需要重新整理頁面,以查看類似上述內容的頁面。
檢查應用程式檔案
這個資料夾包含您在步驟 1 中看到的同一組檔案,但系統變更了 main.py
和 templates/index.html
這兩個檔案,該程式已改為檢索 IAP 在要求標頭中提供的使用者資訊,且範本現在也會顯示該項資料。
main.py
中有兩行可取得 IAP 提供的身分識別資料:
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 提供且名稱不區分大小寫,因此,您可以視需要全部大寫或全部大寫。render_template 語句現在包含這些值,因此可以顯示:
page = render_template('index.html', email=user_email, id=user_id)
index.html 範本能以雙大括號括住名稱,即可顯示這些值:
Hello, {{ email }}! Your persistent ID is {{ id }}.
如您所見,提供的資料前方會加上 accounts.google.com
:顯示資訊來源。應用程式可視需要移除包括半形冒號在內的所有內容,以取得原始值。
停用 IAP
如果停用或以某種方式 (例如透過同一個雲端專案中執行的其他應用程式) 略過 IAP,會對應用程式有什麼影響?停用 IAP 以查看後續影響。
在 Cloud 控制台視窗中,依序點選頁面左上方的「選單」圖示 >「安全性」,然後點選「Identity-Aware Proxy」。按一下 App Engine 應用程式旁邊的 IAP 切換鈕,即可關閉 IAP。 |
系統會提醒您,停用 IAP 後所有使用者都可以存取該應用程式。
重新整理應用程式網頁您應該會看到相同的頁面,但沒有顯示任何使用者資訊:
應用程式目前未受到保護,因此使用者可以發送看似透過 IAP 傳送的網頁要求。舉例來說,透過 Cloud Shell 執行下列 curl 指令即可 (請將 <your-url-here> 替換成應用程式的正確網址):
curl -X GET <your-url-here> -H "X-Goog-Authenticated-User-Email: totally fake email"
網頁會顯示在指令列中,如下所示:
<!doctype html> <html> <head> <title>IAP Hello User</title> </head> <body> <h1>Hello World</h1> <p> Hello, totally fake email! Your persistent ID is None. </p> <p> This is step 2 of the <em>User Authentication with IAP</em> codelab. </p> </body> </html>
應用程式無法知道 IAP 是否遭到停用或略過。如果可能有潛在風險,步驟 3 會顯示解決方案。
5. 步驟 3:使用加密編譯驗證
如果 IAP 可能遭到停用或略過,您的應用程式可確認收到的身分資訊是否有效。這會使用 IAP 新增的第三個網路要求標頭,稱為 X-Goog-IAP-JWT-Assertion
。該標頭的值是以加密編譯方式簽署的物件,也包含使用者身分資料。應用程式可驗證數位簽章,並使用該物件中提供的資料確保這個簽章是出自 IAP,未經修改。
數位簽章驗證需要幾個額外的步驟,例如檢索最新的 Google 公開金鑰。您可以根據使用者可能停用或略過 IAP 的可能性,以及應用程式的敏感度,決定應用程式是否需要這些額外步驟。
此為步驟 3,最後一個步驟則是在 iap-codelab/2-HelloUser
資料夾中開啟 Cloud Shell。變更為用來執行這個步驟的資料夾:
cd ~/iap-codelab/3-HelloVerifiedUser
部署至 App Engine
將應用程式部署至 Python 3.7 適用的 App Engine 標準環境:
gcloud app deploy
當系統詢問您是否要繼續時,請輸入 Y 表示「是」。部署應該會在幾分鐘內完成。等待過程中,您可以按照下方說明檢查應用程式檔案。
部署作業準備就緒時,您會收到訊息,您可以使用 gcloud app browse
查看應用程式。輸入該指令。如果瀏覽器未開啟新分頁,請將顯示的連結複製到新分頁正常開啟。
提醒您,您已經在步驟 2 中停用 IAP,因此系統並未將 IAP 資料提供給應用程式。您應該會看到類似以下頁面:
如同之前的情況,系統可能需要幾分鐘才能將最新版本上線,屆時才能看到新版頁面。
IAP 已停用,因此沒有提供使用者資訊。現在重新啟用 IAP。
在 Cloud 控制台視窗中,依序點選頁面左上方的「選單」圖示 >「安全性」,然後點選「Identity-Aware Proxy」。按一下 App Engine 應用程式旁邊的 IAP 切換鈕,即可再次啟用 IAP。 |
重新整理頁面。頁面應如下所示:
請注意,透過已驗證方法提供的電子郵件地址不含 accounts.google.com:
前置字元。
如果停用或略過 IAP,經過驗證的資料會遺失或失效,原因是不具備有效簽章,除非是由 Google 私密金鑰持有者所建立的資料。
檢查應用程式檔案
這個資料夾內含與步驟 2 中相同的一組檔案,其中兩個檔案有所不同,一個是新的檔案。新檔案是 auth.py
,提供的 user()
方法可擷取及驗證經加密簽署的身分資訊。已變更的檔案包括 main.py
和 templates/index.html
,現在會使用該方法的結果。系統也會顯示步驟 2 中的未經驗證標頭,方便您進行比較。
新功能主要位於 user()
函式中:
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']
assertion
是指定要求標頭中提供的加密簽署資料。該程式碼會使用程式庫驗證並解碼該資料。驗證作業採用 Google 提供的公開金鑰檢查相關簽署資料,並瞭解資料目標對象 (基本上是指受到保護的 Google Cloud 專案)。輔助函式 keys()
和 audience()
會收集並傳回這些值。
已簽署的物件含有我們需要的兩項資料:已驗證的電子郵件地址,以及專屬 ID 值 (由 sub
針對訂閱者、標準欄位提供)。
這樣步驟 3 就完成了。
6. 摘要
您部署了 App Engine 網頁應用程式。在步驟 1 中,您已限制應用程式存取權,只允許您選擇的使用者存取。在步驟 2 中,您擷取並顯示受 IAP 允許存取您應用程式的使用者身分,並且看到瞭如果停用或規避 IAP 停用或略過 IAP 之後可能遭到假冒的資訊。在步驟 3 中,您驗證了使用者身分的加密簽署斷言,因此無法遭人假冒。
7. 清除
您在本程式碼研究室中只使用 App Engine 執行個體。每次部署應用程式時,系統都會建立新版本,直到刪除為止。離開研究室即可刪除專案和當中的所有資源。