Signing in users with SAML

This document shows you how to use Identity Platform to sign in users with a Security Assertion Markup Language (SAML) 2.0 provider.

Before you begin

  1. Sign in to your Google Account.

    If you don't already have one, sign up for a new account.

  2. In the Cloud Console, on the project selector page, select or create a Cloud project.

    Go to the project selector page

  3. Make sure that billing is enabled for your Google Cloud project. Learn how to confirm billing is enabled for your project.

  4. Enable Identity Platform, and add the Client SDK to your app. See the Quickstart to learn how.

Configuring the provider

  1. Go to the Identity Providers page in the Cloud Console.
    Go to the Identity Providers page

  2. Click Add a Provider, and select SAML from the list.

  3. Enter the following details:

    1. The Name of the provider. This can be the same as the provider ID, or a custom name. If you enter a custom name, click Edit next to Provider ID to specify the ID (which must begin with saml.).

    2. The provider's Entity ID.

    3. The provider's SAML SSO URL.

    4. The certificate used for token-signing on the provider. Make sure to include the start and end strings. For example:

      -----BEGIN CERTIFICATE-----
      MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czEL
      ...
      LEzc1JwEGQQVDYQCwsQMSBDAF0QAB0w9GikhqkgBNADABIgABIwAgOdACCjaCIIM
      -----END CERTIFICATE-----
      
  4. Under Service provider, enter the Entity ID of your app. This is typically your app's URL. On your SAML identity provider, this is referred to as the audience.

  5. Add your app to the list of Authorized Domains. For example, if your app's sign-in URL is https://example.com/login, add example.com.

  6. If necessary, customize the callback URL for your app. This is commonly called the Assertion Consumer Service (ACS) URL by SAML identity providers.

    Using the default callback URL reduces the complexity of validating the SAML response. If you customize this flow, make sure the Identity Platform callback URL for your project is configured on your SAML identity provider. This usually looks something like https://<authDomain>/__/auth/handler. See Customizing an authentication handler to learn more.

  7. Click Save.

Signing requests

You can increase the security of your authentication requests by signing them.

To sign requests, first enable signed requests for your identity provider by calling inboundSamlConfigs.patch(), and setting idp_config.sign_request to true:

REST

HTTP method and URL:

PATCH https://identitytoolkit.googleapis.com/admin/v2/projects/project-id/inboundSamlConfigs/provider-id?updateMask=idpConfig.signRequest

Request JSON body:

{
  "idp_config": {
    "sign_request": true
  }
}

To send your request, expand one of these options:

 

You must use the REST API to enable signed requests; using the Cloud Console or gcloud command-line tool is not supported.

The response is an InboundSamlConfig object, which includes an array of SpCertificate. Configure the value of the X509 certificate with your SAML identity provider so it can validate the signature of your requests.

Signing in users

When you sign a user in, the Client SDK handles the authentication handshake, then returns ID tokens containing the SAML attributes in their payloads. To sign a user in and get attributes from the SAML provider:

  1. Create a SAMLAuthProvider instance with the provider ID you configured in the previous section. The provider ID must start with saml..

    const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');
    
  2. Start the sign in flow. You can choose to either use a popup or a redirect.

    To show a popup, call signInWithPopup():

    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 error.
      });
    

    Redirect

    To redirect to a sign-in page, call signInWithRedirect():

    firebase.auth().signInWithRedirect(provider);
    

    Then, call getRedirectResult() to get the results when the user returns to your app:

    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 error.
      });
    
  3. Retrieve the user attributes associated with the SAML provider from the ID token using the firebase.sign_in_attributes claim. Make sure to verify the ID token using the Admin SDK when you send it to your server.

Currently, only service-provider initiated SAML flows from the Client SDK are supported.

Linking user accounts

If a user has already signed in to your app using a different method (such as email/password), you can link their existing account to the SAML provider using linkWithPopup() or linkWithRedirect(). For example:

const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');

// Link with a popup.
firebase.auth().currentUser.linkWithPopup(provider)
    // currentUser.providerData now has an additional entry for this provider.
  }).catch((error) => {
    // Handle error.
  });

Re-authenticating users

Certain sensitive operations, like updating a user's email or password, require the user to have signed in recently. To sign a user in again, call reauthenticateWithPopup() or reauthenticateWithRedirect(). For example:

const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');

// Reauthenticate with a popup.
firebase.auth().currentUser.reauthenticateWithPopup(provider)
  .then((result) => {
    // Get the updated ID token.
    return result.user.getIdTokenResult();
  })
  .then((idTokenResult) => {
    // idTokenResult.authTime should be updated to reflect recent sign-in status.
    // idTokenResult.token has the latest ID token.
  })
  .catch((error) => {
    // Handle error.
  });

What's next