透過 SAML 登入使用者
本文說明如何使用 Identity Platform,透過安全宣告標記語言 (SAML) 2.0 供應商登入使用者帳戶。
事前準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- 啟用 Identity Platform,並將用戶端 SDK 新增至應用程式。如要瞭解做法,請參閱快速入門。
前往 Google Cloud 控制台的「Identity Providers」(識別資訊提供者) 頁面。
前往「Identity Providers」(識別資訊提供者) 頁面按一下「新增供應商」,然後從清單中選取「SAML」。
輸入下列詳細資訊:
供應商名稱。這可以與供應商 ID 相同,也可以是自訂名稱。如果輸入自訂名稱,請按一下「供應商 ID」旁的「編輯」,指定 ID (必須以
saml.
開頭)。供應商的實體 ID。
供應商的 SAML 單一登入網址。
用於簽署提供者權杖的憑證。請務必加入開始和結束字串。例如:
-----BEGIN CERTIFICATE----- MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czEL ... LEzc1JwEGQQVDYQCwsQMSBDAF0QAB0w9GikhqkgBNADABIgABIwAgOdACCjaCIIM -----END CERTIFICATE-----
在「服務供應商」下方,輸入應用程式的「實體 ID」。這通常是應用程式的網址。在 SAML 識別資訊提供者中,這稱為對象。
將應用程式新增至「已授權網域」清單。舉例來說,如果應用程式的登入網址為
https://example.com/login
,請新增example.com
。視需要自訂應用程式的回呼網址。SAML 身分識別提供者通常將此網址稱為宣告客戶服務 (ACS) 網址。
使用預設回呼網址可降低驗證 SAML 回應的複雜度。如果您自訂這個流程,請務必在 SAML 識別資訊提供者上,設定專案的 Identity Platform 回呼網址。這通常看起來像
https://[PROJECT-ID].firebaseapp.com/__/auth/handler
。 詳情請參閱「自訂驗證處理常式」。按一下 [儲存]。
project-id
: Google Cloud 專案的 IDprovider-id
:SAML 提供者 ID使用您在前一節中設定的供應商 ID,建立
SAMLAuthProvider
執行個體。提供者 ID 的開頭必須是saml.
。網頁版 9
import { SAMLAuthProvider } from "firebase/auth"; const provider = new SAMLAuthProvider("saml.myProvider");
網頁版 8
const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');
啟動登入流程。你可以選擇使用彈出式視窗或重新導向。
彈出式視窗
網頁版 9
import { getAuth, signInWithPopup, SAMLAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // User is signed in. // Provider data available from the result.user.getIdToken() // or from result.user.providerData }).catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The AuthCredential type that was used. const credential = SAMLAuthProvider.credentialFromError(error); // Handle / display error. // ... });
網頁版 8
firebase.auth().signInWithPopup(provider) .then((result) => { // User is signed in. // Identity provider data available in result.additionalUserInfo.profile, // or from the user's ID token obtained from result.user.getIdToken() // as an object in the firebase.sign_in_attributes custom claim // This is also available from result.user.getIdTokenResult() // idTokenResult.claims.firebase.sign_in_attributes. }) .catch((error) => { // Handle / display error. // ... });
重新導向
如要重新導向至登入頁面,請呼叫
signInWithRedirect()
:網頁版 9
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
網頁版 8
firebase.auth().signInWithRedirect(provider);
接著,在使用者返回應用程式時呼叫
getRedirectResult()
取得結果:網頁版 9
import { getAuth, getRedirectResult, SAMLAuthProvider } from "firebase/auth"; const auth = getAuth(); getRedirectResult(auth) .then((result) => { // User is signed in. // Provider data available from the result.user.getIdToken() // or from result.user.providerData }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The AuthCredential type that was used. const credential = SAMLAuthProvider.credentialFromError(error); // Handle / display error. // ... });
網頁版 8
firebase.auth().getRedirectResult() .then((result) => { // User is signed in. // Provider data available in result.additionalUserInfo.profile, // or from the user's ID token obtained from result.user.getIdToken() // as an object in the firebase.sign_in_attributes custom claim // This is also available from result.user.getIdTokenResult() // idTokenResult.claims.firebase.sign_in_attributes. }).catch((error) => { // Handle / display error. // ... });
使用
firebase.sign_in_attributes
聲明,從 ID 權杖擷取與 SAML 提供者相關聯的使用者屬性。請務必在將 ID 權杖傳送至伺服器時,使用 Admin SDK 驗證權杖。只有在身分識別提供者的 SAML 聲明中提供
NameID
屬性時,ID 權杖才會包含使用者的電子郵件地址:<Subject> <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@email.com</NameID> </Subject>
這項資訊會填入 Firebase 簽發的 ID 權杖和 UserInfo 物件。
設定提供者
供應商必要元素
Identity Platform 預期供應商的回應中會包含 <saml:Subject>
和 <saml:NameID>
元素。
如果您在設定供應商時未定義這些元素的值,SAML 斷言就會失敗。
簽署要求
您可以簽署驗證要求,提高安全性。
如要簽署要求,請先呼叫 inboundSamlConfigs.patch()
,並將 idp_config.sign_request
設為 true
,為身分識別資訊提供者啟用已簽署的要求:
REST
使用任何要求資料之前,請先替換以下項目:
HTTP 方法和網址:
PATCH https://identitytoolkit.googleapis.com/admin/v2/projects/project-id/inboundSamlConfigs/provider-id?updateMask=idpConfig.signRequest
JSON 要求主體:
{ "idp_config": { "sign_request": true } }
如要傳送要求,請展開以下其中一個選項:
您必須使用 REST API 啟用已簽署的要求,不支援使用Google Cloud 控制台或 Google Cloud CLI。
回應是 InboundSamlConfig
物件,其中包含 SpCertificate
陣列。向 SAML 識別資訊提供者設定 X509 憑證的值,以便驗證要求的簽章。
登入的使用者
登入使用者時,用戶端 SDK 會處理驗證交握,然後傳回 ID 權杖,其中包含酬載中的 SAML 屬性。如要登入使用者並從 SAML 提供者取得屬性,請按照下列步驟操作:
目前僅支援從用戶端 SDK 啟動的服務供應商 SAML 流程。
連結使用者帳戶
如果使用者已透過其他方法 (例如電子郵件/密碼) 登入應用程式,您可以使用 linkWithPopup()
或 linkWithRedirect()
將現有帳戶連結至 SAML 提供者:
舉例來說,我們可以連結 Google 帳戶:
網頁版 9
import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth"; const provider = new GoogleAuthProvider(); const auth = getAuth(); linkWithPopup(auth.currentUser, provider).then((result) => { // Accounts successfully linked. const credential = GoogleAuthProvider.credentialFromResult(result); const user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });
網頁版 8
auth.currentUser.linkWithPopup(provider).then((result) => { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });