Iniciar sessão de utilizadores com SAML

Este documento mostra como usar a Identity Platform para iniciar sessão de utilizadores com um fornecedor de Linguagem de marcação de declaração de segurança (SAML) 2.0.

Antes de começar

  1. 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.
  2. 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 (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. 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 (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Ative a Identity Platform e adicione o SDK do cliente à sua app. Consulte o Início rápido para saber como.
  7. Configurar o fornecedor

    1. Aceda à página Fornecedores de identidade na Google Cloud consola.
      Aceda à página Fornecedores de identidade

    2. Clique em Adicionar um fornecedor e selecione SAML na lista.

    3. Introduza os seguintes detalhes:

      1. O Nome do fornecedor. Pode ser igual ao ID do fornecedor ou um nome personalizado. Se introduzir um nome personalizado, clique em Editar junto a ID do fornecedor para especificar o ID (que tem de começar por saml.).

      2. O ID de entidade do fornecedor.

      3. O URL de SSO de SAML do fornecedor.

      4. O certificado usado para a assinatura de tokens no fornecedor. Certifique-se de que inclui as strings de início e de fim. Por exemplo:

        -----BEGIN CERTIFICATE-----
        MIICajCCAdOgAwIBAgIBADANBgkqhkiG9w0BAQ0FADBSMQswCQYDVQQGEwJ1czEL
        ...
        LEzc1JwEGQQVDYQCwsQMSBDAF0QAB0w9GikhqkgBNADABIgABIwAgOdACCjaCIIM
        -----END CERTIFICATE-----
        
    4. Em Fornecedor de serviços, introduza o ID da entidade da sua app. Normalmente, este é o URL da app. No seu Fornecedor de identidade SAML, isto é denominado público.

    5. Adicione a sua app à lista de Domínios autorizados. Por exemplo, se o URL de início de sessão da sua app for https://example.com/login, adicione example.com.

    6. Se necessário, personalize o URL de retorno de chamada para a sua app. Este é normalmente denominado URL do serviço de consumo de afirmações (ACS) pelos fornecedores de identidade SAML.

      A utilização do URL de retorno predefinido reduz a complexidade da validação da resposta SAML. Se personalizar este fluxo, certifique-se de que o URL de retorno de chamada do Identity Platform para o seu projeto está configurado no seu fornecedor de identidade SAML. Normalmente, tem um aspeto semelhante a https://[PROJECT-ID].firebaseapp.com/__/auth/handler. Consulte o artigo Personalizar um controlador de autenticação para saber mais.

    7. Clique em Guardar.

    Elementos obrigatórios do fornecedor

    A Identity Platform espera os elementos <saml:Subject> e <saml:NameID> nas respostas do fornecedor. Se não definir valores para estes elementos ao configurar o seu fornecedor, a declaração SAML falha.

    Pedidos de assinatura

    Pode aumentar a segurança dos seus pedidos de autenticação assinando-os.

    Para assinar pedidos, primeiro ative os pedidos assinados para o seu fornecedor de identidade: chamando inboundSamlConfigs.patch()> e definindo idp_config.sign_request como true:

    REST

    Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

    • project-id: o ID do projeto Google Cloud
    • provider-id: o ID do fornecedor SAML

    Método HTTP e URL:

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

    Corpo JSON do pedido:

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

    Para enviar o seu pedido, expanda uma destas opções:

     

    Tem de usar a API REST para ativar pedidos assinados. A utilização da Google Cloud consola ou da CLI Google Cloud não é suportada.

    A resposta é um objeto InboundSamlConfig, que inclui uma matriz de SpCertificate. Configure o valor do certificado X509 com o seu fornecedor de identidade SAML para que possa validar a assinatura dos seus pedidos.

    Iniciar sessão de utilizadores

    Quando um utilizador inicia sessão, o SDK do cliente processa o handshake de autenticação e, em seguida, devolve tokens de ID que contêm os atributos SAML nas respetivas cargas úteis. Para iniciar sessão de um utilizador e obter atributos do fornecedor SAML:

    1. Crie uma instância SAMLAuthProvider com o ID do fornecedor que configurou na secção anterior. O ID do fornecedor tem de começar com saml..

      Versão Web 9

      import { SAMLAuthProvider } from "firebase/auth";
      
      const provider = new SAMLAuthProvider("saml.myProvider");

      Versão Web 8

      const provider = new firebase.auth.SAMLAuthProvider('saml.myProvider');
    2. Inicie o fluxo de início de sessão. Pode optar por usar um pop-up ou um redirecionamento.

      Versão 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.
          // ...
        });

      Versão 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.
          // ...
        });

      Redirecionar

      Para redirecionar para uma página de início de sessão, chame signInWithRedirect():

      Versão Web 9

      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);

      Versão Web 8

      firebase.auth().signInWithRedirect(provider);

      Em seguida, chame getRedirectResult() para obter os resultados quando o utilizador regressar à sua app:

      Versão 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.
          // ...
        });

      Versão 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.
          // ...
        });
    3. Recupere os atributos do utilizador associados ao fornecedor SAML do token de ID através da reivindicação firebase.sign_in_attributes. Certifique-se de que valida o token de ID através do SDK de administrador quando o envia para o seu servidor.

      O token de ID inclui o endereço de email do utilizador apenas se for fornecido no atributo NameID da declaração SAML do fornecedor de identidade:

      <Subject>
        <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@email.com</NameID>
      </Subject>
      

      Este campo é preenchido no token de ID emitido pelo Firebase e no objeto UserInfo.

    Atualmente, apenas são suportados fluxos SAML iniciados pelo fornecedor de serviços a partir do SDK do cliente.

    Associar contas de utilizador

    Se um utilizador já tiver iniciado sessão na sua app através de um método diferente (como email/palavra-passe), pode associar a respetiva conta existente ao fornecedor de SAML através de linkWithPopup() ou linkWithRedirect(): Por exemplo, podemos associar a uma Conta Google:

    Versão 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.
      // ...
    });

    Versão Web 8

    auth.currentUser.linkWithPopup(provider).then((result) => {
      // Accounts successfully linked.
      var credential = result.credential;
      var user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    O que se segue?