如要搭配使用外部身分和 Identity-Aware Proxy (IAP),應用程式必須有登入頁面。IAP 會將使用者重新導向至這個頁面,以便在他們存取安全資源前進行驗證。
本文說明如何使用 Cloud Run 部署及自訂預先建構的登入頁面。這是開始使用外部身分最快的方式,而且不需要編寫任何程式碼。
您也可以自行建立登入頁面。自行建構頁面難度較高,但可進一步控管驗證流程和使用者體驗。詳情請參閱「使用 FirebaseUI 建立登入頁面」和「建立自訂登入頁面」。
登入頁面限制
如果專案已啟用電子郵件列舉防護功能,就無法使用預先建構的登入頁面。
如果專案已啟用電子郵件列舉防護功能,請先停用電子郵件列舉防護功能,再繼續執行本文件中的程序。
事前準備
啟用 Compute Engine API。
啟用外部身分,並在設定期間選取「Create a sign-in page for me」選項。Cloud Run 和 FirebaseUI 就能為您建立登入頁面。
確認 Cloud Run 使用的服務帳戶 PROJECT_NUMBER-compute@developer.gserviceaccount.com具備下列預先定義的角色:
roles/identitytoolkit.viewerroles/iap.settingsAdminroles/compute.networkViewer
設定 Identity Platform 提供者的授權重新導向 URI
如果您使用的 Identity Platform 提供者需要登入重新導向 (重新導向至外部 IdP 登入頁面)。您必須在供應商設定中,將託管登入頁面的網址新增為授權重新導向網址。
舉例來說,如果是 Google 供應商,您需要執行下列操作:
選取受 IAP 保護的應用程式後,複製「Login URL」(登入網址)。
前往 Google Cloud 控制台的「Credentials」(憑證) 頁面。
將
LOGIN_URL/__/auth/handler新增為應用程式 OAuth 2.0 用戶端的其中一個授權重新導向 URI。選取設定 Google 供應商時使用的 OAuth 用戶端 ID。
如果是其他 SAML 和 OIDC 供應商,請同樣新增 LOGIN_URL/__/auth/handler 做為授權重新導向 URI 或 ACS 網址。
測試登入頁面
IAP 建立的初始登入頁面功能完整。測試方法如下:
前往受 IAP 保護的資源。系統應會自動將您重新導向登入頁面。
選取要用來登入的租戶和提供者。如果畫面上未列出任何租戶或供應商,請確認您已使用 Identity Platform 設定。
使用憑證登入。
系統應會將您重新導向至受保護的資源。
自訂登入頁面
您可以使用 JSON 設定檔自訂登入頁面。其中一些選項包括:
- 在登入頁面中加入標頭和標誌。
- 指定可用的租戶和供應商。
- 自訂每個租戶和供應商按鈕的圖示和樣式。
- 新增應用程式隱私權政策和服務條款的連結。
以下各節說明如何存取及更新 JSON 設定檔。
取得存取權杖
如要管理登入頁面,您需要 Google 存取權杖。最簡單的方法是將 Google 啟用為 Identity Platform 的提供者。如果應用程式已使用 Google 做為識別資訊提供者,可以略過本節。
前往Google Cloud 控制台的「Identity Platform Providers」(Identity Platform 供應商) 頁面。
按一下「Add a Provider」。
從供應商清單中選取「Google」。
設定「Web Client ID」和「Web Client Secret」:
前往 Google Cloud 控制台的「Credentials」(憑證) 頁面。
使用現有的 OAuth 2.0 用戶端,或建立新的用戶端。將
Client ID和Client secret設為網頁用戶端 ID 和網頁用戶端密鑰。將LOGIN_URL/__/auth/handler新增為 OAuth 2.0 用戶端的其中一個已授權重新導向 URI。LOGIN_URL是選取「建立登入頁面」選項後,由 IAP 建立的登入網址。在 Google Cloud 控制台的「IAP」頁面選取受 IAP 保護的資源,即可找到這項資訊。
在兩個頁面中都按一下「儲存」。
登入管理面板
Cloud Run 代管登入頁面的 JSON 設定,位於「LOGIN_URL/admin」面板。下列步驟說明如何存取面板。請注意,您必須具備 Storage 管理員 (roles/storage.admin) 角色。
前往 Google Cloud 控制台的「IAP」頁面。
從清單中選取資源。
啟動資訊面板中「Customize page」(自訂頁面) 下方列出的網址。看起來應該像
https://servicename-xyz-uc.a.run.app/admin。使用設定 IAP 時所用的 Google 帳戶登入。系統會顯示含有 JSON 設定檔的文字編輯器。
修改設定
登入頁面的設定結構定義是以 FirebaseUI 為基礎,並沿用其許多屬性。您可以改用 PROJECT_ID.firebaseapp.com,而非 IAP 建立的 LOGIN_URL 做為預設 authDomain。
如要使用 PROJECT_ID.firebaseapp.com 做為 authDomain,請將 signInFlow 變更為 popup,避免在主要瀏覽器上發生第三方儲存空間存取問題(請參閱「在封鎖第三方儲存空間存取權的瀏覽器上使用 signInWithRedirect 的最佳做法」)。此外,請按照「設定 Identity Platform 供應商的授權重新導向 URI 」一文的指示,將 PROJECT_ID.firebaseapp.com/__/auth/handler 新增為使用者登入時所用 Identity Platform 供應商的授權重新導向 URI 或 ACS 網址。
以下程式碼範例顯示包含三個租戶的設定:
{
"AIzaSyC5DtmRUR...": {
"authDomain": "awesomeco.firebaseapp.com",
"displayMode": "optionFirst",
"selectTenantUiTitle": "Awesome Company Portal",
"selectTenantUiLogo": "https://awesome.com/abcd/logo.png",
"styleUrl": "https://awesome.com/abcd/overrides/stylesheet.css",
"tosUrl": "https://awesome.com/abcd/tos.html",
"privacyPolicyUrl": "https://awesome.com/abcd/privacypolicy.html",
"tenants": {
"tenant-a-id": {
"fullLabel": "Company A Portal",
"displayName": "Company A",
"iconUrl": "https://companya.com/img/icon.png",
"logoUrl": "https://companya.com/img/logo.png",
"buttonColor": "#007bff",
"signInFlow": "popup",
"signInOptions": [
{
"provider": "password",
"requireDisplayName": false,
"disableSignUp": {
"status": true,
"adminEmail": "admin@example.com",
"helpLink": "https://www.example.com/trouble_signing_in"
}
},
"facebook.com",
"google.com",
"microsoft.com",
{
"provider": "saml.okta-cicp-app",
"providerName": "Corp Account",
"fullLabel": "Employee Corporate Login",
"buttonColor": "#ff0000",
"iconUrl": "https://companya.com/abcd/icon-1.png"
},
{
"provider": "oidc.okta-oidc",
"providerName": "Contractor Account",
"fullLabel": "Contractor Account Portal",
"buttonColor": "#00ff00",
"iconUrl": "https://companya.com/abcd/icon-2.png"
}
],
"tosUrl": "https://companya.com/abcd/tos.html",
"privacyPolicyUrl": "https://companya.com/abcd/privacypolicy.html"
},
"tenant-b-id": {
"fullLabel": "Company B Portal",
"displayName": "Company B",
"iconUrl": "https://companyb.com/img/icon.png",
"logoUrl": "https://companyb.com/img/logo.png",
"buttonColor": "#007bff",
"immediateFederatedRedirect": true,
"signInFlow": "popup",
"signInOptions": [
{
"provider": "saml.okta-bla-app",
"providerName": "Corp Account",
"buttonColor": "#0000ff",
"iconUrl": "https://companyb.com/abcd/icon.png"
}
],
"tosUrl": "https://companyb.com/abcd/tos.html",
"privacyPolicyUrl": "https://companyb.com/abcd/privacypolicy.html"
},
"tenant-c-id": {
"fullLabel": "Company C Portal",
"displayName": "Company C",
"iconUrl": "https://companyc.com/img/icon.png",
"logoUrl": "https://companyc.com/img/logo.png",
"buttonColor": "#007bff",
"immediateFederatedRedirect": true,
"signInFlow": "popup",
"signInOptions": [
{
"provider": "password",
"requireDisplayName": false
},
{
"provider": "google.com",
"scopes": ["scope1", "scope2", "https://example.com/scope3"],
"loginHintKey": "login_hint",
"customParameters": {
"prompt": "consent",
},
}
],
"tosUrl": "https://companyc.com/abcd/tos.html",
"privacyPolicyUrl": "https://companyc.com/abcd/privacypolicy.html",
"adminRestrictedOperation": {
"status": true,
"adminEmail": "admin@example.com",
"helpLink": "https://www.example.com/trouble_signing_in"
}
},
}
}
}
如需可用屬性的完整清單,請參閱參考文件。
覆寫 CSS
您可以使用 styleUrl 屬性指定自訂 CSS 檔案。這個檔案中的樣式會覆寫預設 CSS。檔案必須可透過 HTTPS 公開存取 (例如託管於 Cloud Storage bucket)。
以下範例示範如何覆寫預設 CSS:
/** Change header title style. */
.heading-center {
color: #7181a5;
font-family: Arial, Helvetica, sans-serif;
font-size: 20px;
font-weight: bold;
}
/** Use round edged borders for container. */
.main-container {
border-radius: 5px;
}
/** Change page background color. */
body {
background-color: #e6eaf0;
}
重新部署 Cloud Run 服務
在某些情況下,您可能需要重新部署託管登入頁面的 Cloud Run 服務。情境範例包括:
- 新增、修改或移除識別資訊提供者
- 修改租戶設定
- 設定環境變數
- 將容器映像檔更新至最新版本
定期更新及重新部署容器映像檔,可確保您取得最新的錯誤修正和安全性修補程式。您可以在 GitHub 查看版本之間的變更清單。
您可以使用 /versionz 端點,取得已部署容器的目前版本。例如:
curl 'https://servicename-xyz-uc.a.run.app/versionz'
如要重新部署 Cloud Run 服務,請按照下列步驟操作:
前往 Google Cloud 控制台的「Cloud Run」頁面。
選取託管登入頁面的服務。
點選「編輯及部署新的修訂版本」。
您也可以指定修訂版本的進階設定,或按一下「Variables & Secrets」(變數與密鑰) 分頁標籤來新增環境變數。
點選「Deploy」(部署)。
進階選項
透過程式輔助方式自訂登入頁面
除了使用 /admin 控制台,您也可以透過程式輔助方式更新 JSON 設定。
如要取得目前的設定,請使用 /get_admin_config 端點。例如:
curl -H 'Authorization: Bearer [TOKEN]'
'https://servicename-xyz-uc.a.run.app/get_admin_config'
如要更新設定,請使用 /set_admin_config。例如:
curl -XPOST -H 'Authorization: Bearer [TOKEN]' -H "Content-type: application/json"
-d '[UPDATED-CONFIG]' 'https://servicename-xyz-uc.a.run.app/set_admin_config'
這兩個 REST 呼叫都需要 https://www.googleapis.com/auth/devstorage.read_write 範圍,且有效的 OAuth 權杖必須附加至 Authorization 標頭。
設定環境變數
您可以在 Cloud Run 服務上設定環境變數,自訂進階設定。下表列出可用的變數:
| 變數 | 說明 |
|---|---|
DEBUG_CONSOLE |
布林值 (0 或 1),表示是否要記錄所有網路要求錯誤和詳細資料。系統不會記錄機密資料。預設為停用 (0)。
|
UI_CONFIG |
包含登入頁面 JSON 設定的字串。使用這個變數而非 /admin 面板,可避免在存取設定時讀取及寫入 Cloud Storage。系統會忽略無效的設定。設定這個變數前,請先使用 /admin 面板驗證 JSON,盡可能減少語法錯誤。 |
GCS_BUCKET_NAME |
覆寫預設 Cloud Storage bucket 的字串,用於儲存 JSON 設定。檔案名稱為 config.json,預設位置為 gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER]。 |
ALLOW_ADMIN |
布林值 (0 或 1),指出是否允許存取 /admin 設定面板。預設為啟用 (1)。
|
更新變數後,您必須部署新版 Cloud Run 服務,變更才會生效。如要進一步瞭解環境變數,請參閱 Cloud Run 說明文件。
自訂網域
根據預設,使用者登入時會看到 Cloud Run 服務的網址。如要改為指定自訂網域,請按照下列步驟操作:
按照「對應自訂網域」中的步驟,為 Cloud Run 服務設定自訂網域。
設定 IAP 使用新的驗證網址:
前往 Google Cloud 控制台的「IAP」頁面。
選取受 IAP 保護的資源。
在側邊面板中,選取「Login URL」(登入網址) 欄位旁的「Edit」(編輯) 圖示。
選取「Use an existing hosted sign-in page」,然後從下拉式選單中選擇網域。
按一下 [儲存]。
多項 IAP 資源共用一個登入頁面
您可以使用同一個登入頁面保護多項 IAP 資源。這可減少管理多項設定的工作。
如要重複使用登入頁面,請按照下列步驟操作:
請按照本文中的步驟,為第一個受 IAP 保護的資源部署驗證頁面。
為第二項資源啟用 IAP。系統提示您指定登入頁面時,請選取「I'll provide my own」(我會自行提供),然後輸入 Cloud Run 服務的網址做為「URL」(網址)。
重新部署 Cloud Run 服務。
疑難排解
託管登入頁面無法使用服務
使用託管登入頁面時,您會收到下列錯誤訊息:
Service unavailable
因此無法存取登入頁面。
如要解決這項錯誤,請執行下列操作:
確認預設 Cloud Storage bucket 的格式為
gcip-iap-bucket-CLOUD_RUN_SERVICE_NAME-PROJECT-NUMBER。確認預設 Cloud Storage bucket 存在,且包含名為
config.json的檔案。
瀏覽器中的第三方 Cookie 和儲存空間分區
如果瀏覽器停用第三方 Cookie 或實施儲存空間分區,登入頁面或 admin/ 頁面可能無法正常運作。如要解決這個問題,請按照下列步驟操作:
重新部署登入頁面,以使用最新的 1.0.1 版。
如果您自訂登入頁面,請務必將
authDomain設為 IAP 建立的LOGIN_URL。或者,如果signInFlow設為popup,您可以將authDomain設為PROJECT_ID.firebaseapp.com。下列程式碼片段顯示自訂登入頁面的
authDomain設定:{ "AIzaSyC5DtmRUR...": { "authDomain": "LOGIN_URL", ... } }下列程式碼片段說明
popup登入頁面的authDomain:{ "AIzaSyC5DtmRUR...": { "authDomain": "PROJECT_ID.firebaseapp.com", "tenants": { "tenant-a-id": { ... "signInFlow": "popup" ... } } ... } }