Como hospedar uma página de login com o Cloud Run

Para usar identidades externas com o Identity-Aware Proxy (IAP), seu app precisa de uma página de login. O IAP redirecionará os usuários para esta página para autenticação antes que eles acessem recursos seguros.

Este documento mostra como implantar e personalizar uma página de login pré-criada usando o Cloud Run. Essa é a maneira mais rápida de começar a usar identidades externas e não requer que você escreva código.

Também é possível criar uma página de login por conta própria. Criar a própria página é mais difícil, mas aumenta o controle sobre o fluxo de autenticação e a experiência do usuário. Para saber mais, consulte Como criar uma página de login com o FirebaseUI e Como criar uma página de login personalizada.

Limitações da página de login

Não é possível usar a página de login pré-criada se o projeto tiver a proteção contra enumeração de e-mails ativada.

Caso seu projeto esteja com a proteção contra enumeração de e-mails ativada, desative a proteção contra enumeração de e-mails antes de continuar os procedimentos neste documento.

Antes de começar

  • Ative a API Compute Engine.

    Ativar a API do Compute Engine

  • Ative identidades externas e selecione a opção Criar uma página de login para mim durante a configuração. Isso permite O Cloud Run e a FirebaseUI criam uma página de login para você.

  • Verifique se a conta de serviço usada pelo Cloud Run, PROJECT_NUMBER-compute@developer.gserviceaccount.com, tem os seguintes papéis predefinidos:

    • roles/identitytoolkit.viewer
    • roles/iap.settingsAdmin
    • roles/compute.networkViewer

Como definir o URI de redirecionamento autorizado para provedores do Identity Platform

Se você usa provedores do Identity Platform que exigem redirecionamento de login (redirecionamento para a página de login do IdP externo). Adicione o URL da página de login hospedada como um URL de redirecionamento autorizado na configuração do provedor.

Por exemplo, no caso de um provedor do Google, faça o seguinte:

  1. Copie o URL de login depois de selecionar o aplicativo protegido pelo IAP.

  2. No Console do Google Cloud, acesse a página Credenciais.

    Acessar "Credenciais"

  3. Adicione LOGIN_URL/__/auth/handler como um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0 do seu app. Selecione o mesmo ID do cliente OAuth usado ao configurar o provedor do Google.

Para outros provedores SAML e OIDC, faça o mesmo adicionando LOGIN_URL/__/auth/handler como o URI de redirecionamento autorizado ou o URL ACS.

Como testar a página de login

A página de login inicial criada pelo IAP é totalmente funcional. Para testar:

  1. Acesse um recurso protegido pelo IAP. Você será redirecionado automaticamente para a página de login.

  2. Selecione um locatário e um provedor para fazer login. Se você não encontrar nenhum locatário ou provedor listado, verifique se configurou um usando o Identity Platform.

  3. Faça login com suas credenciais.

Você será redirecionado para o recurso protegido.

Como personalizar a página de login

É possível personalizar a página de login usando um arquivo de configuração JSON. Veja algumas opções:

  • Adicionar um cabeçalho e um logotipo à página de login.
  • Especificar os locatários e provedores disponíveis.
  • Como personalizar os ícones e o estilo de cada locatário e botão de provedor.
  • Adição de links para a política de privacidade e os Termos de Serviço do app.

Nas seções a seguir, explicamos como acessar e atualizar o arquivo de configuração JSON.

Como conseguir um token de acesso

Para administrar a página de login, você precisa de um token de acesso do Google. A maneira mais fácil de conseguir uma é ativar o Google como um provedor do Identity Platform. Se o app já usa o Google como provedor de identidade, pule esta seção.

  1. Acesse a página Provedores do Identity Platform na console do Google Cloud.

    Acessar a página "Provedores do Identity Platform"

  2. Clique em Adicionar um provedor.

  3. Selecione Google na lista de provedores.

  4. Configure o ID do cliente da Web e a chave secreta do cliente da Web:

    1. No Console do Google Cloud, acesse a página Credenciais.

      Acessar "Credenciais"

    2. Use um cliente OAuth 2.0 ou crie um novo. Configure Client ID e Client secret como o ID do cliente da Web e a chave secreta do cliente da Web. Adicione LOGIN_URL/__/auth/handler como um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0. O LOGIN_URL é o URL de login. criado pelo IAP após selecionar a opção Criar uma página de login para mim. Ele pode ser encontrado na página do IAP no console do Google Cloud, selecionando o recurso protegido por IAP.

  5. Clique em Salvar nas duas páginas.

Como fazer login no painel do administrador

A configuração JSON para a página de login hospedada pelo Cloud Run no painel LOGIN_URL/admin. As etapas a seguir mostram como acessar o painel. Você precisará do parâmetro Administrador do Storage (roles/storage.admin).

  1. Acesse a página IAP no console do Google Cloud.

    Acessar a página do IAP

  2. Selecione seu recurso na lista.

  3. Inicie o URL listado em Personalizar página no painel de informações. Ele precisa ser semelhante a este: https://servicename-xyz-uc.a.run.app/admin.

  4. Faça login com a mesma Conta do Google usada para configurar o IAP. Será exibido um editor de texto contendo o arquivo de configuração JSON.

Como modificar a configuração

O esquema de configuração da página de login é baseado na FirebaseUI e herda muitas das propriedades dela. Em vez de usar o LOGIN_URL criado pelo IAP como o authDomain padrão, use PROJECT_ID.firebaseapp.com.

Se você quiser usar PROJECT_ID.firebaseapp.com como authDomain, mude signInFlow como popup para evitar problemas de acesso ao armazenamento de terceiros nos principais navegadores. Consulte Práticas recomendadas para usar o signInWithRedirect em navegadores que bloqueiam o acesso ao armazenamento de terceiros. Além disso, siga as instruções em Configurar URI de redirecionamento autorizado para provedores do Identity Platform para adicionar o PROJECT_ID.firebaseapp.com/__/auth/handler como um dos URIs de redirecionamento autorizados ou URLs de ACS para o provedor do Identity Platform com que os usuários vão fazer login.

O código a seguir mostra um exemplo do Terraform com três locatários:

{
  "AIzaSyC5DtmRUR...": {
    "authDomain": "awesomeco.firebaseapp.com",
    "displayMode": "optionFirst",
    "selectTenantUiTitle": "Awesome Company Portal",
    "selectTenantUiLogo": "https://awesome.com/abcd/logo.png",
    "styleUrl": "https://awesome.com/abcd/overrides/stylesheet.css",
    "tosUrl": "https://awesome.com/abcd/tos.html",
    "privacyPolicyUrl": "https://awesome.com/abcd/privacypolicy.html",
    "tenants": {
      "tenant-a-id": {
        "fullLabel": "Company A Portal",
        "displayName": "Company A",
        "iconUrl": "https://companya.com/img/icon.png",
        "logoUrl": "https://companya.com/img/logo.png",
        "buttonColor": "#007bff",
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "password",
            "requireDisplayName": false,
            "disableSignUp": {
              "status": true,
              "adminEmail": "admin@example.com",
              "helpLink": "https://www.example.com/trouble_signing_in"
            }
          },
          "facebook.com",
          "google.com",
          "microsoft.com",
          {
            "provider": "saml.okta-cicp-app",
            "providerName": "Corp Account",
            "fullLabel": "Employee Corporate Login",
            "buttonColor": "#ff0000",
            "iconUrl": "https://companya.com/abcd/icon-1.png"
          },
          {
            "provider": "oidc.okta-oidc",
            "providerName": "Contractor Account",
            "fullLabel": "Contractor Account Portal",
            "buttonColor": "#00ff00",
            "iconUrl": "https://companya.com/abcd/icon-2.png"
          }
        ],
        "tosUrl": "https://companya.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companya.com/abcd/privacypolicy.html"
      },
      "tenant-b-id": {
        "fullLabel": "Company B Portal",
        "displayName": "Company B",
        "iconUrl": "https://companyb.com/img/icon.png",
        "logoUrl": "https://companyb.com/img/logo.png",
        "buttonColor": "#007bff",
        "immediateFederatedRedirect": true,
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "saml.okta-bla-app",
            "providerName": "Corp Account",
            "buttonColor": "#0000ff",
            "iconUrl": "https://companyb.com/abcd/icon.png"
          }
        ],
        "tosUrl": "https://companyb.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companyb.com/abcd/privacypolicy.html"
      },
      "tenant-c-id": {
        "fullLabel": "Company C Portal",
        "displayName": "Company C",
        "iconUrl": "https://companyc.com/img/icon.png",
        "logoUrl": "https://companyc.com/img/logo.png",
        "buttonColor": "#007bff",
        "immediateFederatedRedirect": true,
        "signInFlow": "popup",
        "signInOptions": [
          {
            "provider": "password",
            "requireDisplayName": false
          },
          {
            "provider": "google.com",
            "scopes": ["scope1", "scope2", "https://example.com/scope3"],
            "loginHintKey": "login_hint",
            "customParameters": {
              "prompt": "consent",
            },
          }
        ],
        "tosUrl": "https://companyc.com/abcd/tos.html",
        "privacyPolicyUrl": "https://companyc.com/abcd/privacypolicy.html",
        "adminRestrictedOperation": {
          "status": true,
          "adminEmail": "admin@example.com",
          "helpLink": "https://www.example.com/trouble_signing_in"
        }
      },
    }
  }
}

Para uma lista completa das propriedades disponíveis, consulte a documentação de referência.

Modificação do CSS

É possível usar a propriedade styleUrl para especificar um arquivo CSS personalizado. Os estilos neste arquivo modificarão o CSS padrão. O arquivo precisa ser de acesso público usando HTTPS. Por exemplo, hospedado em um bucket do Cloud Storage.

O exemplo a seguir demonstra a modificação do CSS padrão:

/** Change header title style. */
.heading-center {
  color: #7181a5;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
  font-weight: bold;
}

/** Use round edged borders for container. */
.main-container {
  border-radius: 5px;
}

/** Change page background color. */
body {
  background-color: #f8f9fa;
}

Como reimplantar a instância do Cloud Run

Em alguns casos, reimplante a instância do Cloud Run que hospeda a página de login. Exemplos de cenários:

  • Adicionar, modificar ou remover provedores de identidade
  • Como modificar configurações de locatário
  • Definir variáveis de ambiente
  • Como atualizar a imagem do contêiner para a versão mais recente

Atualizar e reimplantar regularmente a imagem do contêiner garante que você tenha as correções de bug e os patches de segurança mais recentes. Veja a lista de alterações entre as versões no GitHub.

É possível conseguir a versão atual do contêiner implantado usando o endpoint /versionz. Exemplo:

curl 'https://servicename-xyz-uc.a.run.app/versionz'

Para reimplantar a instância do Cloud Run:

  1. Acesse a página do Cloud Run no console do Google Cloud.

    Acessar a página do Cloud Run

  2. Selecione a instância que hospeda a página de login.

  3. Clique em Editar e implantar nova revisão.

  4. Se quiser, especifique configurações avançadas para a revisão ou adicione uma variável de ambiente clicando na guia Variáveis e secrets.

  5. Clique em Deploy.

Opções avançadas

Como personalizar a página de login de maneira programática

Além de usar o console /admin, é possível atualizar a configuração JSON de maneira programática.

Para ver a configuração atual, use o endpoint /get_admin_config. Exemplo:

curl -H 'Authorization: Bearer [TOKEN]'
  'https://servicename-xyz-uc.a.run.app/get_admin_config'

Para atualizar a configuração, use /set_admin_config. Exemplo:

curl -XPOST -H 'Authorization: Bearer [TOKEN]' -H "Content-type: application/json"
  -d '[UPDATED-CONFIG]' 'https://servicename-xyz-uc.a.run.app/set_admin_config'

As duas chamadas REST exigem o escopo https://www.googleapis.com/auth/devstorage.read_write, e um token OAuth válido precisa ser anexado ao cabeçalho Authorization.

Definir variáveis de ambiente

É possível definir variáveis de ambiente na instância do Cloud Run para personalizar as configurações avançadas. A tabela a seguir lista as variáveis disponíveis:

Variável Descrição
DEBUG_CONSOLE Um valor booleano (0 ou 1) que indica se todos os erros e detalhes de solicitações de rede serão registrados. Os dados confidenciais não serão registrados. Essa configuração (0) está desativada por padrão.
UI_CONFIG Uma string contendo a configuração JSON para a página de login. Usar essa variável em vez do painel /admin evita a leitura e a gravação em um Cloud Storage ao acessar a configuração. Configurações inválidas são ignoradas. Usar o painel /admin para validar o JSON antes de definir essa variável pode ajudar a minimizar erros de sintaxe.
GCS_BUCKET_NAME Uma string que modifica o bucket padrão do Cloud Storage usado para armazenar a configuração JSON. O nome do arquivo é config.json e o local padrão é gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN Um valor booleano (0 ou 1) que indica se o acesso ao painel de configuração /admin será permitido. 1: ativado por padrão.

Você precisará implantar uma nova revisão da instância do Cloud Run depois de atualizar as variáveis antes que as alterações entrem em vigor. Para saber mais sobre variáveis de ambiente, consulte a documentação do Cloud Run.

Como personalizar o domínio

Por padrão, os usuários veem o URL da instância do Cloud Run ao fazer login. Para especificar um domínio personalizado:

  1. Siga as etapas em Como mapear domínios personalizados para definir um domínio personalizado para a instância do Cloud Run.

  2. Configure o IAP para usar o novo URL de autenticação:

    1. Acesse a página do IAP no console do Google Cloud.

      Acessar a página do IAP

    2. Selecione o recurso protegido pelo IAP.

    3. No painel lateral, selecione o ícone Editar ao lado do campo URL de login.

    4. Selecione Usar uma página de login hospedada atual e escolha seu domínio no menu suspenso.

    5. Clique em Save.

Como usar uma página de login para vários recursos do IAP

É possível proteger vários recursos do IAP usando a mesma página de login. Isso reduz o trabalho associado ao gerenciamento de várias configurações.

Para reutilizar uma página de login:

  1. Siga as etapas neste artigo para implantar a página de autenticação do primeiro recurso protegido pelo IAP.

  2. Ative o IAP para o segundo recurso. Quando você precisar especificar uma página de login, selecione Fornecerei meu próprio URL e digite o URL do serviço do Cloud Run como o URL.

  3. Reimplante o serviço do Cloud Run.

Solução de problemas

Cookies de terceiros e particionamento de armazenamento em navegadores

Para navegadores que desativam cookies de terceiros ou implementam particionamento de armazenamento, a página de login ou a página de administrador pode não funcionar corretamente. Para resolver esse problema, faça o seguinte:

  1. Reimplante a página de login para usar a versão mais recente 1.0.1.

  2. Se você usar o recurso Personalizar a página de login, verifique se authDomain está definido como o LOGIN_URL que o IAP criou. Como alternativa, defina authDomain como PROJECT_ID.firebaseapp.com se signInFlow estiver definido como popup.

    {
      "AIzaSyC5DtmRUR...": {
        "authDomain": "LOGIN_URL",
        ...
      }
    }
    

    ou

    {
      "AIzaSyC5DtmRUR...": {
        "authDomain": "PROJECT_ID.firebaseapp.com",
        "tenants": {
          "tenant-a-id": {
            ...
            "signInFlow": "popup"
            ...
          }
        }
        ...
      }
    }
    

A seguir