透過程式管理 SAML 和 OIDC 供應商
本文說明如何使用 Identity Platform Admin SDK,以程式輔助方式管理安全宣告標記語言 (SAML) 2.0 和 OpenID Connect (OIDC) 提供者設定。
使用 Admin SDK,您可以自動設定供應商、執行基本 CRUD 作業、輪替憑證等。如果供應商數量眾多,使用 Google Cloud 控制台手動管理會很麻煩,這時這個方法就很有用。
事前準備
與 SAML 提供者合作
建立 SAML 提供者設定
建立 SAML 供應商設定時,您需要提供下列參數。您可能需要參閱身分識別提供者的說明文件,瞭解如何取得部分值。
- 顯示名稱
- 設定的好記顯示名稱。這個名稱也是 Google Cloud 控制台中的供應商標籤。
- 已啟用
- 目前供應器設定是否已啟用或停用。使用者無法透過已停用的提供者登入。
- 供應商 ID
-
供應商的專屬 ID,開頭為
saml.。 - 識別資訊提供者實體 ID
- 供應商的實體 ID。
- 單一登入 (SSO) 網址
- 提供者的 SAML 單一登入 (SSO) 網址。網址必須有效。
- X.509 憑證
-
SAML 提供者 X.509 憑證清單,包括
-----BEGIN CERTIFICATE-----和-----END CERTIFICATE----字串。這些金鑰用於在識別資訊提供者上簽署權杖。Identity Platform 收到 SAML 回應時,會使用記錄中的憑證驗證簽章。如果驗證失敗,系統會拒絕回應。金鑰輪替時,您必須更新這些憑證。建議上傳多個憑證,以免輪替期間發生服務中斷。
- 中繼方實體 ID
- SAML 依賴方 (RP/SP) 實體 ID。這通常是應用程式的網址。在 SAML 識別資訊提供者中,這稱為「對象」。
- 回呼網址
-
驗證完成時要返回的網址。SAML 供應商通常將此稱為「宣告客戶服務 (ACS) 網址」。您必須向 SAML 供應商註冊這個網址。 看起來應該像這樣:
https://PROJECT-ID.firebaseapp.com/__/auth/handler, 與 Google Cloud 控制台中顯示的網址類似。如要瞭解詳情,請參閱「透過 SAML 登入使用者」。使用預設回呼網址可降低驗證 SAML 回應的複雜度。不過,您也可以選擇顯示自訂網域。 在這種情況下,請確認專案的 Identity Platform 回呼網址已正確設定 SAML 識別資訊提供者。通常看起來會像這樣:
https://AUTH-DOMAIN/__/auth/handler。
以下範例說明如何建立 SAML 提供者設定:
Node.js
const newConfig = {
displayName: 'SAML provider name',
enabled: true,
providerId: 'saml.myProvider',
idpEntityId: 'IDP_ENTITY_ID',
ssoURL: 'https://example.com/saml/sso/1234/'
x509Certificates: [
'-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
'-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
],
rpEntityId: 'RP_ENTITY_ID',
// Using the default callback URL.
callbackURL: 'https://project-id.firebaseapp.com/__/auth/handler',
};
admin.auth().createProviderConfig(newConfig).then(() => {
// Successful creation.
}).catch((error) => {
// Handle error.
});
Go
newConfig := (&auth.SAMLProviderConfigToCreate{}). DisplayName("SAML provider name"). Enabled(true). ID("saml.myProvider"). IDPEntityID("IDP_ENTITY_ID"). SSOURL("https://example.com/saml/sso/1234/"). X509Certificates([]string{ "-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----", }). RPEntityID("RP_ENTITY_ID"). CallbackURL("https://project-id.firebaseapp.com/__/auth/handler") saml, err := client.CreateSAMLProviderConfig(ctx, newConfig) if err != nil { log.Fatalf("error creating SAML provider: %v\n", err) } log.Printf("Created new SAML provider: %s", saml.ID)
Python
saml = auth.create_saml_provider_config( display_name='SAML provider name', enabled=True, provider_id='saml.myProvider', idp_entity_id='IDP_ENTITY_ID', sso_url='https://example.com/saml/sso/1234/', x509_certificates=[ '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----', '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----', ], rp_entity_id='P_ENTITY_ID', callback_url='https://project-id.firebaseapp.com/__/auth/handler') print('Created new SAML provider:', saml.provider_id)
Java
SamlProviderConfig.CreateRequest request = new SamlProviderConfig.CreateRequest() .setDisplayName("SAML provider name") .setEnabled(true) .setProviderId("saml.myProvider") .setIdpEntityId("IDP_ENTITY_ID") .setSsoUrl("https://example.com/saml/sso/1234/") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----") .setRpEntityId("RP_ENTITY_ID") .setCallbackUrl("https://project-id.firebaseapp.com/__/auth/handler"); SamlProviderConfig saml = FirebaseAuth.getInstance().createSamlProviderConfig(request); System.out.println("Created new SAML provider: " + saml.getProviderId());
完成後,這個方法會傳回新建立設定的 SAMLAuthProviderConfig 物件。
更新 SAML 供應商設定
以下範例說明如何修改 SAML 提供者設定。 除了提供者 ID 以外,您都可以更新任何欄位。
Node.js
const updatedConfig = {
x509Certificates: [
'-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
'-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
],
};
admin.auth().updateProviderConfig('saml.myProvider', updatedConfig).then(() => {
// Successful update.
}).catch((error) => {
// Handle error.
});
Go
updatedConfig := (&auth.SAMLProviderConfigToUpdate{}). X509Certificates([]string{ "-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----", }) saml, err := client.UpdateSAMLProviderConfig(ctx, "saml.myProvider", updatedConfig) if err != nil { log.Fatalf("error updating SAML provider: %v\n", err) } log.Printf("Updated SAML provider: %s", saml.ID)
Python
saml = auth.update_saml_provider_config( 'saml.myProvider', x509_certificates=[ '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----', '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----', ]) print('Updated SAML provider:', saml.provider_id)
Java
SamlProviderConfig.UpdateRequest request = new SamlProviderConfig.UpdateRequest("saml.myProvider") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----") .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----"); SamlProviderConfig saml = FirebaseAuth.getInstance().updateSamlProviderConfig(request); System.out.println("Updated SAML provider: " + saml.getProviderId());
完成後,這個方法會傳回更新設定的 SAMLAuthProviderConfig 物件。
取得 SAML 提供者設定
識別 SAML 設定的主要方式是使用供應商 ID。 以下範例說明如何取得 SAML 提供者設定:
Node.js
admin.auth().getProviderConfig('saml.myProvider').then((config) => {
// Get display name and whether it is enabled.
console.log(config.displayName, config.enabled);
}).catch((error) => {
// Handle error. Common error is that config is not found.
});
Go
saml, err := client.SAMLProviderConfig(ctx, "saml.myProvider") if err != nil { log.Fatalf("error retrieving SAML provider: %v\n", err) } log.Printf("%s %t", saml.DisplayName, saml.Enabled)
Python
saml = auth.get_saml_provider_config('saml.myProvider') print(saml.display_name, saml.enabled)
Java
SamlProviderConfig saml = FirebaseAuth.getInstance().getSamlProviderConfig("saml.myProvider"); System.out.println(saml.getDisplayName() + ": " + saml.isEnabled());
如果存在具有指定 ID 的提供者,這個方法會傳回 SAMLAuthProviderConfig 物件。
刪除 SAML 供應商設定
以下範例說明如何刪除 SAML 提供者設定:
Node.js
admin.auth().deleteProviderConfig('saml.myProvider').then(() => {
// Successful deletion.
}).catch((error) => {
// Handle error.
});
Go
if err := client.DeleteSAMLProviderConfig(ctx, "saml.myProvider"); err != nil { log.Fatalf("error deleting SAML provider: %v\n", err) }
Python
auth.delete_saml_provider_config('saml.myProvider')
Java
FirebaseAuth.getInstance().deleteSamlProviderConfig("saml.myProvider");
列出 SAML 提供者設定
以下範例說明如何列出現有的 SAML 供應商設定:
Node.js
// Returns 10 SAML provider configs starting from the specified nextPageToken offset.
admin.auth().listProviderConfigs({type: 'saml', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
results.providerConfigs.forEach((config) => {
console.log(config.providerId);
});
// To list the next 10:
// return admin.auth().listProviderConfigs(
// {type: 'saml', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
// Handle error.
});
Go
iter := client.SAMLProviderConfigs(ctx, "nextPageToken") for { saml, err := iter.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("error retrieving SAML providers: %v\n", err) } log.Printf("%s\n", saml.ID) }
Python
for saml in auth.list_saml_provider_configs('nextPageToken').iterate_all(): print(saml.provider_id)
Java
ListProviderConfigsPage<SamlProviderConfig> page = FirebaseAuth.getInstance() .listSamlProviderConfigs("nextPageToken"); for (SamlProviderConfig config : page.iterateAll()) { System.out.println(config.getProviderId()); }
每批結果都包含供應商設定清單,以及用於擷取下一批結果的下一頁權杖。列出所有供應商後,系統不會傳回任何權杖。
根據預設,每個批次會傳回 100 個供應商。這也是每個批次的供應商數量上限。
與 OIDC 供應商合作
建立 OIDC 提供者設定
建立 OIDC 供應商設定時,您需要提供下列參數。您可能需要參閱身分識別提供者的說明文件,瞭解如何取得部分值。
- 顯示名稱
- 設定的好記顯示名稱。這個名稱也是 Google Cloud 控制台中的供應商標籤。
- 已啟用
- 目前供應器設定是否已啟用或停用。使用者無法透過已停用的提供者登入。
- 供應商 ID
-
供應商的專屬 ID,開頭為
oidc.。 - 用戶端 ID
- 用來確認 OIDC 提供者 ID 權杖對象的 ID。
- 用戶端密鑰
- 啟用 OIDC 程式碼流程時必須提供的用戶端密鑰。
- 核發單位
-
供應商的
Issuer。這應該看起來像https://example.com。Identity Platform 會使用這個網址找出 OIDC 導覽文件 (通常位於/.well-known/openid-configuration),其中會指定 provider 的 OAuth 端點和公開金鑰。Identity Platform 會根據 OpenID Connect 規格驗證 ID 權杖。如果供應商不遵守探索服務的 OIDC 規格,就無法與 Identity Platform 搭配使用。 - 回應類型
-
OAuth 授權流程的供應商回應類型。您可以將 {
idToken,code} 其中一個設為true,但不能同時設為true。如果啟用授權碼流程,您必須提供用戶端密鑰。
以下範例說明如何建立使用隱含授權流程的 OIDC 供應商設定:
Node.js
const newConfig = {
displayName: 'OIDC provider name',
enabled: true,
clientId: 'CLIENT_ID2',
issuer: 'https://oidc.com/CLIENT_ID2',
providerId: 'oidc.provider2',
responseType: {
idToken: true,
code: false,
},
};
admin.auth().createProviderConfig(newConfig).then(() => {
// Successful creation.
}).catch((error) => {
// Handle error.
});
Go
newConfig := (&auth.OIDCProviderConfigToCreate{}). DisplayName("OIDC provider name"). Enabled(true). ID("oidc.myProvider"). ClientID("CLIENT_ID2"). Issuer("https://oidc.com/CLIENT_ID2") oidc, err := client.CreateOIDCProviderConfig(ctx, newConfig) if err != nil { log.Fatalf("error creating OIDC provider: %v\n", err) } log.Printf("Created new OIDC provider: %s", oidc.ID)
Python
oidc = auth.create_oidc_provider_config( display_name='OIDC provider name', enabled=True, provider_id='oidc.myProvider', client_id='CLIENT_ID2', issuer='https://oidc.com/CLIENT_ID2') print('Created new OIDC provider:', oidc.provider_id)
Java
OidcProviderConfig.CreateRequest request = new OidcProviderConfig.CreateRequest() .setDisplayName("OIDC provider name") .setEnabled(true) .setProviderId("oidc.myProvider") .setClientId("CLIENT_ID2") .setIssuer("https://oidc.com/CLIENT_ID2"); OidcProviderConfig oidc = FirebaseAuth.getInstance().createOidcProviderConfig(request); System.out.println("Created new OIDC provider: " + oidc.getProviderId());
完成後,這個方法會傳回新建立設定的 OIDCAuthProviderConfig 物件。
更新 OIDC 提供者設定
以下範例說明如何修改 OIDC 供應商設定。除了提供者 ID 以外,所有欄位都可以更新。
Node.js
const updatedConfig = {
displayName: 'OIDC provider name',
enabled: true,
clientId: 'CLIENT_ID',
clientSecret: 'CLIENT_SECRET'
issuer: 'https://oidc.com/',
responseType: {
code: true,
idToken: false,
},
};
admin.auth().updateProviderConfig('oidc.myProvider', updatedConfig).then(() => {
// Successful update.
}).catch((error) => {
// Handle error.
});
Go
updatedConfig := (&auth.OIDCProviderConfigToUpdate{}). DisplayName("OIDC provider name"). Enabled(true). ClientID("CLIENT_ID"). Issuer("https://oidc.com") oidc, err := client.UpdateOIDCProviderConfig(ctx, "oidc.myProvider", updatedConfig) if err != nil { log.Fatalf("error updating OIDC provider: %v\n", err) } log.Printf("Updated OIDC provider: %s", oidc.ID)
Python
oidc = auth.update_oidc_provider_config( 'oidc.myProvider', client_id='CLIENT_ID', issuer='https://oidc.com') print('Updated OIDC provider:', oidc.provider_id)
Java
OidcProviderConfig.UpdateRequest request = new OidcProviderConfig.UpdateRequest("oidc.myProvider") .setDisplayName("OIDC provider name") .setEnabled(true) .setClientId("CLIENT_ID") .setIssuer("https://oidc.com"); OidcProviderConfig oidc = FirebaseAuth.getInstance().updateOidcProviderConfig(request); System.out.println("Updated OIDC provider: " + oidc.getProviderId());
完成後,這個方法會傳回更新設定的 OIDCAuthProviderConfig 物件。
取得 OIDC 提供者設定
識別 OIDC 設定的主要方式是使用提供者 ID。以下範例說明如何取得 OIDC 提供者設定:
Node.js
admin.auth().getProviderConfig('oidc.myProvider').then((config) => {
// Get display name and whether it is enabled.
console.log(config.displayName, config.enabled);
}).catch((error) => {
// Handle error. Common error is that config is not found.
});
Go
oidc, err := client.OIDCProviderConfig(ctx, "oidc.myProvider") if err != nil { log.Fatalf("error retrieving OIDC provider: %v\n", err) } log.Printf("%s %t", oidc.DisplayName, oidc.Enabled)
Python
oidc = auth.get_oidc_provider_config('oidc.myProvider') print(oidc.display_name, oidc.enabled)
Java
OidcProviderConfig oidc = FirebaseAuth.getInstance().getOidcProviderConfig("oidc.myProvider"); System.out.println(oidc.getDisplayName() + ": " + oidc.isEnabled());
如果存在具有指定 ID 的提供者,這個方法會傳回 OIDCAuthProviderConfig 物件。
刪除 OIDC 供應商設定
以下範例說明如何刪除 OIDC 供應商設定:
Node.js
admin.auth().deleteProviderConfig('oidc.myProvider').then(() => {
// Successful deletion.
}).catch((error) => {
// Handle error.
});
Go
if err := client.DeleteOIDCProviderConfig(ctx, "oidc.myProvider"); err != nil { log.Fatalf("error deleting OIDC provider: %v\n", err) }
Python
auth.delete_oidc_provider_config('oidc.myProvider')
Java
FirebaseAuth.getInstance().deleteOidcProviderConfig("oidc.myProvider");
列出 OIDC 供應商設定
以下範例說明如何列出現有的 OIDC 供應商設定:
Node.js
// Returns 10 OIDC provider configs starting from the specified nextPageToken offset.
admin.auth().listProviderConfigs({type: 'oidc', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
results.providerConfigs.forEach((config) => {
console.log(config.providerId);
});
// To list the next 10:
// return admin.auth().listProviderConfigs(
// {type: 'oidc', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
// Handle error.
});
Go
iter := client.OIDCProviderConfigs(ctx, "nextPageToken") for { oidc, err := iter.Next() if err == iterator.Done { break } if err != nil { log.Fatalf("error retrieving OIDC providers: %v\n", err) } log.Printf("%s\n", oidc.ID) }
Python
for oidc in auth.list_oidc_provider_configs('nextPageToken').iterate_all(): print(oidc.provider_id)
Java
ListProviderConfigsPage<OidcProviderConfig> page = FirebaseAuth.getInstance() .listOidcProviderConfigs("nextPageToken"); for (OidcProviderConfig oidc : page.iterateAll()) { System.out.println(oidc.getProviderId()); }
每批結果都包含供應商設定清單,以及用於擷取下一批結果的下一頁權杖。列出所有供應商後,系統不會傳回任何權杖。
根據預設,每個批次會傳回 100 個供應商。這也是每個批次的供應商數量上限。
後續步驟
- 遷移現有應用程式的使用者。
- 使用 SAML 和 OIDC 讓使用者登入。