SAML プロバイダと OIDC プロバイダをプログラムで管理する

このドキュメントでは、Identity Platform Admin SDK を使用して Security Assertion Markup Language(SAML)2.0 と OpenID Connect(OIDC)のプロバイダ構成をプログラムで管理する方法について説明します。

Admin SDK を使用すると、プロバイダの構成、基本的な CRUD オペレーションの実行、証明書のローテーションなどを行えます。これは、Google Cloud コンソールを使用して手動で管理することが煩雑なプロバイダが多数ある場合に役立ちます。

準備

SAML プロバイダの利用

SAML プロバイダ構成の作成

SAML プロバイダ構成を作成する際は、次のパラメータを指定する必要があります。各値を取得する方法の詳細については、必要に応じて、ID プロバイダのドキュメントをご覧ください。

表示名
構成のわかりやすい表示名。これは、Google Cloud コンソールにおけるプロバイダ ラベルでもあります。
有効
現在のプロバイダ構成の有効 / 無効。無効なプロバイダではログインできません。
プロバイダ ID
saml. で始まるプロバイダの一意の ID。
ID プロバイダのエンティティ ID
プロバイダのエンティティ ID。
SSO の URL
プロバイダの SAML SSO URL。URL は有効なものである必要があります。
X.509 証明書

SAML プロバイダの X.509 証明書のリスト。証明書には、-----BEGIN CERTIFICATE----------END CERTIFICATE---- の文字列を含みます。これは、ID プロバイダのトークン署名に使用されます。

Identity Platform は、SAML レスポンスを受信すると、記録されている証明書を使用して署名を検証します。検証で不合格だと、レスポンスは拒否されます。証明書は、鍵がローテーションされると、更新する必要があります。ローテーション中のサービス停止を防ぐために、複数の証明書をアップロードすることを検討してください。

リライング パーティ エンティティ ID
SAML リライング パーティ(RP/SP)のエンティティ ID。通常は、アプリの URL です。SAML ID プロバイダでは、オーディエンスと呼ばれます。
コールバック URL

認証の完了時に返される URL。通常、SAML プロバイダでは、ACS URL(Assertion Consumer Service URL)と呼ばれています。この URL を SAML プロバイダに登録する必要があります。Google Cloud コンソールに表示される URL と同様、https://PROJECT-ID.firebaseapp.com/__/auth/handler という形式の URL になります。詳細については、SAML を使用したユーザーのログインをご覧ください。

デフォルトのコールバック URL を使用すると、SAML レスポンスを検証する複雑さが軽減されます。ただし、カスタム ドメインを表示することもできます。この場合、プロジェクトの Identity Platform コールバック URL が SAML ID プロバイダで正しく構成されていることを確認してください。通常、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());
}

結果の各バッチにはプロバイダ構成のリストと、次のバッチを取得するために使用されるページトークンが含まれます。すべてのプロバイダが表示されると、トークンは返されません。

デフォルトでは、1 バッチあたり 100 件のプロバイダが返されます。また、1 バッチあたりの最大プロバイダ数も 100 件です。

OIDC プロバイダの操作

OIDC プロバイダ構成の作成

OIDC プロバイダ構成を作成する際は、次のパラメータを指定する必要があります。各値を取得する方法の詳細については、必要に応じて、ID プロバイダのドキュメントをご覧ください。

表示名
構成のわかりやすい表示名。これは、Google Cloud コンソールにおけるプロバイダ ラベルでもあります。
有効
現在のプロバイダ構成の有効 / 無効。無効なプロバイダではログインできません。
プロバイダ ID
oidc. で始まるプロバイダの一意の ID。
クライアント ID
OIDC プロバイダの ID トークンのオーディエンスを確認するために使用される ID。
クライアント シークレット
OIDC コードフローを有効にするために必要なクライアント シークレット。
発行元
プロバイダの Issuerhttps://example.com のようになります。Identity Platform は、この URL を使用して、プロバイダの OAuth エンドポイントと公開鍵を指定する OIDC ディスカバリ ドキュメント(通常は /.well-known/openid-configuration にあります)を検索します。Identity Platform は OpenID Connect 仕様に従って ID トークンを検証します。プロバイダが検出用の OIDC 仕様に準拠していない場合、Identity Platform では使用できません。
レスポンス タイプ
OAuth 認証フローに関するプロバイダのレスポンス タイプ。{idToken, code} のいずれかを 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());
}

結果の各バッチにはプロバイダ構成のリストと、次のバッチを取得するために使用されるページトークンが含まれます。すべてのプロバイダが表示されると、トークンは返されません。

デフォルトでは、1 バッチあたり 100 件のプロバイダが返されます。また、1 バッチあたりの最大プロバイダ数も 100 件です。

次のステップ