驗證網路應用程式的使用者通常是必要的部分,而且通常需要在應用程式中進行特殊的程式設計作業。如果是 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。內含不相關的概念和程式碼區塊會重疊在外,可供您直接複製並貼上。
您將在 Cloud Shell 指令列環境中工作。首先,請開啟該環境並擷取範例程式碼。
啟動主控台和 Cloud Shell
在研究室頁面的左上角,按一下 [開啟 Google 主控台] 按鈕。您必須使用按鈕下方顯示的「使用者名稱和密碼」登入。 |
這個程式碼研究室中的所有指令都會在 Cloud Shell 中為你建立並開啟的專案執行。按一下主控台頁面標頭右側的「啟用 Cloud Shell」圖示,開啟 Cloud Shell。網頁下半部可讓您輸入和執行指令。 這些指令可以透過您自己的電腦執行,但您必須先安裝並設定所需的開發軟體。Cloud Shell 已提供您需要的所有軟體工具。 |
下載程式碼
按一下 Cloud Shell 中的指令列區域,即可輸入指令。從 Github 擷取程式碼,然後變更為程式碼資料夾:
git clone https://github.com/googlecodelabs/user-authentication-with-iap.git
cd iap-codelab
這個資料夾包含一個程式碼資料夾,其中包含此程式碼研究室每個步驟。您將變更為正確的資料夾以執行每個步驟。
這是以 Python 3.7 編寫的 App Engine 標準環境應用程式,其中只會顯示「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 Console 視窗中,按一下頁面左上角的選單圖示,然後依序點選 [安全性] 和 [Identity-Aware Proxy]。 | |
這是您第一次為這項專案啟用驗證選項,因此系統會顯示訊息,您必須設定 OAuth 同意畫面,才能使用 IAP。 | |
按一下 [設定確認畫面] 按鈕。系統隨即會開啟新分頁,讓您設定同意畫面。 |
將必要欄位留空,填入適當的值:
應用程式名稱 | 應用程式內購廣告範例 |
支援服務電子郵件地址 | 您的電子郵件地址。系統可能已經為您填入這項資訊。 |
已授權網域 | 應用程式網址的主機名稱部分,例如 iap-example-999999.appspot.com。您可以在先前開啟的 Hello World 網頁的網址列中看到這項資訊。請勿加入網址開頭 請務必在填入這個值後按 Enter 鍵。 |
應用程式首頁連結 | 您用來查看應用程式的網址 |
應用程式隱私權政策連結 | 應用程式中的隱私權頁面連結,與首頁的 /privacy 尾端相同 |
按一下 [儲存]。系統會提示您建立憑證。您不需要為這個程式碼研究室建立憑證,因此只需關閉這個瀏覽器分頁即可。
返回 Identity-Aware Proxy 頁面並重新整理頁面。您應該會看到可供保護的資源清單。 點選 App Engine 應用程式列中的「應用程式內購」欄中的切換按鈕,即可開啟 IAP。 | |
系統會顯示受 IAP 保護的網域名稱。按一下 [開啟]。 | |
現在請開啟瀏覽器分頁,然後前往您的應用程式網址。接著,您會看到「使用 Google 帳戶登入」畫面,您必須登入才能存取應用程式。 | |
使用 Google 或 G Suite 帳戶登入。您會看到一個拒絕存取畫面的畫面。 |
您已成功透過 IAP 保護應用程式,但您尚未通知 IAP 允許哪些帳戶使用。
返回主控台的 Identity-Aware Proxy 頁面並勾選 App Engine 應用程式旁邊的核取方塊,然後查看頁面右側的側欄。 | |
每個要授予存取權限的電子郵件地址 (或 Google 群組地址,或是 G Suite 網域名稱) 都必須新增為成員。按一下 [新增成員]。輸入您的電子郵件地址,然後選擇要指派給該位址的 Cloud IAP/IAP-Secured Web App User 角色。您可以用同樣的方式輸入更多地址或 G Suite 網域。 |
按一下 [儲存]。視窗底部會顯示「政策已更新」訊息。
返回應用程式並重新載入頁面。您應該會看到您的網路應用程式,因為您已用授權的使用者登入。不過,由於 IAP 可能無法重新檢查您的授權,因此您可能還是會看到「您沒有存取權」頁面。在這種情況下,請執行下列步驟:
- 開啟網路瀏覽器並前往首頁網址,並在網址結尾加上
/_gcp_iap/clear_login_cookie
,例如https://iap-example-999999.appspot.com/_gcp_iap/clear_login_cookie
。 - 您會看到新的「使用 Google 帳戶登入」畫面,您的帳戶已經啟用。請勿點選該帳戶。請按一下 [使用其他帳戶] 並重新輸入憑證。
- 執行這些步驟會導致 IAP 重新檢查你的存取權,你現在應該會看到應用程式的主畫面。
如果您可以存取其他瀏覽器,或是在瀏覽器中使用無痕模式,而且擁有另一個有效的 GMail 或 G Suite 帳戶,就可以使用該瀏覽器瀏覽至您的應用程式頁面,然後以另一個帳戶登入。由於該帳戶尚未獲得授權,因此系統會顯示「您沒有存取權」的畫面,而非您的應用程式。
應用程式受到 IAP 保護後,應用程式即可使用 IAP 在網路要求標頭中提供的識別資訊。在這個步驟中,應用程式會取得已登入使用者的電子郵件地址,以及 Google 身分識別服務指派給該使用者的永久專屬使用者 ID。系統會在歡迎頁面中向使用者顯示該資料。
這是步驟 2,最後一個步驟會在 Cloud Shell 中開啟「iap-codelab/1-HelloWorld
」資料夾。變更為此步驟的資料夾:
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')
IAP 提供 X-Goog-Authenticated-User-
標頭,且名稱不區分大小寫,因此可依照全部或全部大寫輸入。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 Console 視窗中,按一下頁面左上角的選單圖示,然後依序點選 [安全性] 和 [Identity-Aware Proxy]。按一下 App Engine 應用程式旁邊的「應用程式內購」切換鈕,即可停用 IAP。 |
您將會收到警告,讓所有使用者存取這個應用程式。
重新整理應用程式網頁。您應該會看到相同的網頁,但是沒有使用者資訊:
由於應用程式目前未受保護,因此使用者可能會傳送透過 IAP 傳送的網路要求。例如,您可以透過 Cloud Shell 執行下列 curl 指令來完成此步驟 (將 <<您的網址>> 替換成您應用程式的正確網址):
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 會顯示解決方案。
如果 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。
在 Cloud Console 視窗中,按一下頁面左上角的選單圖示,然後依序點選 [安全性] 和 [Identity-Aware Proxy]。按一下 App Engine 應用程式旁邊的「應用程式內購」切換鈕,即可重新啟用 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。
您已部署 App Engine 網路應用程式。在步驟 1 中,您只允許應用程式使用者存取該應用程式。在步驟 2 中,您已擷取並顯示使用者身分資訊,表示 IAP 允許存取您的應用程式;此外,如果 IAP 已停用或略過,這些資訊可能會遭到假冒。在步驟 3 中,您驗證了使用者簽署的加密簽署宣告,但此身分無法遭到假冒。
您在這個程式碼研究室中使用的 Google Cloud Platform 資源只有 App Engine 執行個體。每次您部署應用程式時,系統都會建立新的版本並持續存在,直到刪除為止。結束研究室即可刪除專案和其中的所有資源。