SAML を使用したユーザーのログイン
このドキュメントでは、Identity Platform を使用して Security Assertion Markup Language(SAML)2.0 プロバイダでユーザーのログインを行う方法について説明します。
始める前に
- Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify 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.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
- Identity Platform を有効にして、クライアント SDK をアプリに追加します。詳細と手順については、Identity Platform を使用してユーザーがメールアドレスでログインできるようにするクイックスタートをご覧ください。
プロバイダを構成する
Google Cloud コンソールで、[Identity Platform> ID プロバイダ] ページに移動します。
[ID プロバイダ] に移動[プロバイダを追加] をクリックし、リストから [SAML] を選択します。
次の詳細情報を入力します。
プロバイダの名前。プロバイダ ID と同じでも、カスタム名でも構いません。カスタム名を入力する場合は、[プロバイダ ID] の横にある [編集] をクリックして ID を指定します(
samlで始める必要があります)。プロバイダの [エンティティ ID]。
プロバイダの [SAML SSO の URL]。
プロバイダのトークン署名に使用される証明書。必ず開始文字列と終了文字列を含めてください。次に例を示します。
-----BEGIN CERTIFICATE----- MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czEL ... LEzc1JwEGQQVDYQCwsQMSBDAF0QAB0w9GikhqkgBNADABIgABIwAgOdACCjaCIIM -----END CERTIFICATE-----
[サービス提供者] セクションで、アプリの [エンティティ ID] を入力します。これは通常、アプリの URL です。SAML ID プロバイダでは、これはオーディエンスと呼ばれます。
[プロジェクト設定] サイドペインで、[ドメインを追加] をクリックして、アプリのドメインを追加します。たとえば、アプリのログイン URL が
https://example.com/loginの場合、example.comを追加します。設定を完了するには、次のいずれかを行います。
[Authorization callback (URL)] フィールドからデフォルトの認証コールバック URL をコピーし、SAML アプリの構成に追加します。
デフォルトの認証コールバック URL を使用すると、SAML レスポンスを検証する複雑さが軽減されます。
カスタマイズした認証コールバック URL(
https://PROJECT-ID.firebaseapp.com/__/auth/handlerなど)を SAML アプリの構成に追加します。
[アプリケーションの構成] で、[詳細を設定] をクリックします。このスニペットをアプリのコードにコピーして、Identity Platform Client SDK を初期化します。
[保存] をクリックします。
プロバイダで必須の要素
Identity Platform は、プロバイダからのレスポンスに <saml:Subject> 要素と <saml:NameID> 要素を想定しています。プロバイダを構成するときに、これらの要素の値を定義しない場合、SAML アサーションは失敗します。
リクエストへの署名
認証リクエストに署名することで、認証リクエストのセキュリティを強化できます。
リクエストに署名するには、まず inboundSamlConfigs.patch() を呼び出し、idp_config.sign_request を true に設定して、ID プロバイダの署名付きリクエストを有効にします。
REST
リクエストのデータを使用する前に、次のように置き換えます。
project-id: Google Cloud プロジェクトの IDprovider-id: SAML プロバイダ ID
HTTP メソッドと URL:
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 の使用はサポートされていません。
レスポンスは、SpCertificate オブジェクトの配列を含む InboundSamlConfig オブジェクトです。リクエストの署名を検証できるように、X509 証明書の値を SAML ID プロバイダで構成します。
サービス提供者の証明書をローテーションする
署名付き SAML リクエストを使用する場合、Identity Platform はサービス プロバイダ(SP)証明書を使用します。認証の中断を防ぐため、SP 証明書の有効期限をモニタリングし、有効期限が切れる前にローテーションします。
SP 証明書の有効期限を確認するには、
jqを使用して証明書の有効期限のタイムスタンプを抽出します。curl -s -X GET "https://identitytoolkit.googleapis.com/v2/projects/PROJECT_ID/inboundSamlConfigs" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "X-Goog-User-Project: PROJECT_ID" \ -H "Content-Type: application/json" | \ jq -r '.inboundSamlConfigs[].spConfig.spCertificates[]?.expiresAt'PROJECT_IDは、実際の Google Cloudプロジェクト ID に置き換えます。spConfig.spCertificatesの下のexpiresAtの値を確認します。有効期限のタイムスタンプ(
expiresAt)が 30 日以内または組織で必要な期間内の場合は、Cloud カスタマーケアと IdP 管理者に連絡して、予定されているダウンタイム中に更新を計画します。証明書をローテーションして新しい公開証明書を受け取るには、Cloud カスタマーケアにお問い合わせください。
IdP で証明書の設定を更新するには、新しい SP 証明書を IdP 管理者と共有します。
更新された構成でシングル サインオン(SSO)が機能するかどうかをテストします。
ユーザーのログイン
ユーザーをログインさせると、クライアント SDK が認証 handshake を処理し、ペイロードに SAML 属性を含む ID トークンを返します。ユーザーがログインして SAML プロバイダから属性を取得するには、次のようにします。
前のセクションで構成したプロバイダ ID で
SAMLAuthProviderインスタンスを作成します。プロバイダ ID の先頭はsamlにする必要があります。Web バージョン 9
import { SAMLAuthProvider } from "firebase/auth"; const provider = new SAMLAuthProvider("saml.myProvider");
Web バージョン 8
const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');
ログインフローを開始します。ダイアログまたはリダイレクトのいずれかを使用できます。
ポップアップ
Web バージョン 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. // ... });
Web バージョン 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()を呼び出します。Web バージョン 9
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Web バージョン 8
firebase.auth().signInWithRedirect(provider);
次に、
getRedirectResult()を呼び出して、ユーザーがアプリに戻ったときに結果を取得します。Web バージョン 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. // ... });
Web バージョン 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クレームを使用して、SAML プロバイダに関連付けられているユーザー属性を ID トークンから取得します。ID トークンをサーバーに送信するときに、Admin SDK を使用して必ず検証してください。ID トークンには、ID プロバイダからの SAML アサーションの
NameID属性で指定されている場合にのみ、ユーザーのメールアドレスが含まれます。<Subject> <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@email.com</NameID> </Subject>これは、Firebase 発行の ID トークンと UserInfo オブジェクトに入力されます。
クライアント SDK からのサービス プロバイダ主導の SAML フローのみがサポートされています。
ユーザー アカウントをリンクする
ユーザーが別の方法(メールアドレスとパスワードなど)を使用してすでにアプリにログインしている場合は、linkWithPopup() または linkWithRedirect() を使用して既存のアカウントを SAML プロバイダにリンクできます。
次のコード スニペットは、ユーザーの Google アカウントを SAML プロバイダにリンクする方法を示しています。
Web バージョン 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. // ... });
Web バージョン 8
auth.currentUser.linkWithPopup(provider).then((result) => { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });