Alojamento de uma página de início de sessão com o Cloud Run

Para usar identidades externas com o Identity-Aware Proxy (IAP), a sua app precisa de uma página de início de sessão. O IAP vai redirecionar os utilizadores para esta página para autenticação antes de poderem aceder a recursos seguros.

Este documento mostra como implementar e personalizar uma página de início de sessão pré-criada com o Cloud Run. Esta é a forma mais rápida de começar a usar identidades externas e não requer programação.

Também pode criar uma página de início de sessão. A criação da sua própria página é mais difícil, mas aumenta o controlo sobre o fluxo de autenticação e a experiência do utilizador. Consulte os artigos Criar uma página de início de sessão com o FirebaseUI e Criar uma página de início de sessão personalizada para saber mais.

Limitações da página de início de sessão

Não pode usar a página de início de sessão pré-criada se o seu projeto tiver a proteção de enumeração de emails ativada.

Se o seu projeto tiver a proteção de enumeração de emails ativada, desative a proteção de enumeração de emails antes de continuar com os procedimentos neste documento.

Antes de começar

  • Ative a API Compute Engine.

    Ative a API Compute Engine

  • Ative as identidades externas e selecione a opção Criar uma página de início de sessão para mim durante a configuração. Isto permite que o Cloud Run e a FirebaseUI criem uma página de início de sessão para si.

  • Certifique-se de que a conta de serviço usada pelo Cloud Run, PROJECT_NUMBER-compute@developer.gserviceaccount.com, tem as seguintes funções predefinidas:

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

Definir o URI de redirecionamento autorizado para fornecedores da Identity Platform

Se usar fornecedores da Identity Platform que requerem o redirecionamento de início de sessão (redirecionamento para a página de início de sessão do IdP externo). Tem de adicionar o URL da página de início de sessão alojada como um URL de redirecionamento autorizado na configuração do fornecedor.

Por exemplo, para um fornecedor da Google, tem de fazer o seguinte:

  1. Copie o URL de início de sessão depois de selecionar a aplicação protegida pelo IAP.

  2. Na Google Cloud consola, aceda à página Credenciais.

    Aceder a Credenciais

  3. Adicione LOGIN_URL/__/auth/handler como um dos URIs de redirecionamento autorizados para o cliente OAuth 2.0 da sua app. Selecione o mesmo ID de cliente OAuth que usou quando configurou o fornecedor Google.

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

Testar a página de início de sessão

A página de início de sessão inicial criada pela IAP está totalmente funcional. Para testar:

  1. Navegue para um recurso protegido pelo IAP. Deve ser feito o redirecionamento automático para a página de início de sessão.

  2. Selecione um inquilino e um fornecedor com os quais iniciar sessão. Se não vir nenhum inquilino nem fornecedor listado, certifique-se de que configurou um através da Identity Platform.

  3. Inicie sessão com as suas credenciais.

Deve ser feito o redirecionamento para o recurso protegido.

Personalizar a página de início de sessão

Pode personalizar a página de início de sessão através de um ficheiro de configuração JSON. Algumas opções incluem:

  • Adicionar um cabeçalho e um logótipo à página de início de sessão.
  • Especificar os inquilinos e os fornecedores disponíveis.
  • Personalizar os ícones e o estilo de cada botão de inquilino e fornecedor.
  • Adicionar links para a política de privacidade e os termos de utilização da sua app.

As secções seguintes explicam como aceder e atualizar o ficheiro de configuração JSON.

Obter um token de acesso

Para administrar a página de início de sessão, precisa de um token de acesso da Google. A forma mais fácil de obter um é ativar a Google como fornecedor para a Identity Platform. Se a sua app já usa a Google como fornecedor de identidade, pode ignorar esta secção.

  1. Aceda à página Fornecedores da Identity Platform na Google Cloud consola.

    Aceda à página Fornecedores da Identity Platform

  2. Clique em Adicionar um fornecedor.

  3. Selecione Google na lista de fornecedores.

  4. Configure o ID de cliente Web e o segredo do cliente Web:

    1. Na Google Cloud consola, aceda à página Credenciais.

      Aceder a Credenciais

    2. Use um cliente OAuth 2.0 existente ou crie um novo. Configure o Client ID e o Client secret para ID de cliente Web e segredo do cliente 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 início de sessão criado pela IAP depois de selecionar a opção Crie uma página de início de sessão para mim. Pode encontrá-lo na página IAP na Google Cloud consola, selecionando o recurso protegido pelo IAP.

  5. Clique em Guardar em ambas as páginas.

Iniciar sessão no painel de administração

A configuração JSON para a página de início de sessão alojada pelo Cloud Run no painel LOGIN_URL/admin. Os passos seguintes mostram como aceder ao painel. Tenha em atenção que precisa da função de administrador do armazenamento (roles/storage.admin).

  1. Aceda à página IAP na Google Cloud consola.

    Aceda à página de CIs

  2. Selecione o recurso na lista.

  3. Inicie o URL apresentado em Personalizar página no painel de informações. Deve ter um aspeto semelhante a https://servicename-xyz-uc.a.run.app/admin.

  4. Inicie sessão com a mesma Conta Google que usou para configurar as compras na app. É apresentado um editor de texto com o ficheiro de configuração JSON.

Modificar a configuração

O esquema de configuração da página de início de sessão baseia-se no FirebaseUI e herda muitas das respetivas propriedades. Em vez de usar o IAP criado LOGIN_URL como o authDomain predefinido, pode usar PROJECT_ID.firebaseapp.com.

Se quiser usar PROJECT_ID.firebaseapp.com como authDomain, altere signInFlow como popup para evitar o problema de acesso ao armazenamento de terceiros nos principais navegadores(consulte as práticas recomendadas para usar signInWithRedirect em navegadores que bloqueiam o acesso ao armazenamento de terceiros). Além disso, siga as instruções em Definir o URI de redirecionamento autorizado para fornecedores da Identity Platform para adicionar o PROJECT_ID.firebaseapp.com/__/auth/handler como um dos URIs de redirecionamento autorizados ou URLs do ACS para o fornecedor da Identity Platform com o qual os utilizadores vão iniciar sessão.

O código seguinte mostra um exemplo de configuração com três inquilinos:

{
  "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 ver uma lista completa das propriedades disponíveis, consulte a documentação de referência.

Substituir CSS

Pode usar a propriedade styleUrl para especificar um ficheiro CSS personalizado. Os estilos neste ficheiro substituem o CSS predefinido. O ficheiro tem de estar acessível publicamente através de HTTPS (por exemplo, alojado num contentor do Cloud Storage).

O exemplo seguinte demonstra a substituição do CSS predefinido:

/** 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;
}

Voltar a implementar a instância do Cloud Run

Em alguns casos, pode querer voltar a implementar a instância do Cloud Run que aloja a página de início de sessão. Exemplos de cenários:

  • Adicionar, modificar ou remover fornecedores de identidade
  • Modificar configurações de inquilinos
  • Definir variáveis de ambiente
  • Atualizar a imagem do contentor para a versão mais recente

A atualização e a reimplementação regulares da imagem do contentor garantem que tem as correções de erros e os patches de segurança mais recentes. Pode ver a lista de alterações entre versões no GitHub.

Pode obter a versão atual do contentor implementado através do ponto final /versionz. Por exemplo:

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

Para reimplementar a instância do Cloud Run:

  1. Aceda à página Cloud Run na Google Cloud consola.

    Aceda à página do Cloud Run

  2. Selecione a instância que aloja a página de início de sessão.

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

  4. Opcionalmente, especifique definições avançadas para a revisão ou adicione uma variável de ambiente clicando no separador Variáveis e segredos.

  5. Clique em Implementar.

Opções avançadas

Personalizar a página de início de sessão por programação

Além de usar a consola /admin, pode atualizar a configuração JSON de forma programática.

Para obter a configuração atual, use o ponto final /get_admin_config. Por 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. Por 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'

Ambas as chamadas REST requerem o âmbito https://www.googleapis.com/auth/devstorage.read_write e um token OAuth válido tem de estar anexado ao cabeçalho Authorization.

Definir variáveis de ambiente

Pode definir variáveis de ambiente na instância do Cloud Run para personalizar as definições avançadas. A tabela seguinte lista as variáveis disponíveis:

Variável Descrição
DEBUG_CONSOLE Um valor booleano (0 ou 1) que indica se devem ser registados todos os erros e detalhes dos pedidos de rede. Os dados confidenciais não são registados. Desativado (0) por predefinição.
UI_CONFIG Uma string que contém a configuração JSON para a página de início de sessão. A utilização desta variável em vez do painel /admin evita a leitura e a escrita num Cloud Storage quando acede à configuração. As configurações inválidas são ignoradas. A utilização do painel /admin para validar o JSON antes de definir esta variável pode ajudar a minimizar os erros de sintaxe.
GCS_BUCKET_NAME Uma string que substitui o contentor do Google Cloud Storage predefinido usado para armazenar a configuração JSON. O ficheiro tem o nome config.json e a localização predefinida é gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN Um valor booleano (0 ou 1) que indica se deve permitir o acesso ao painel de configuração /admin. Ativada (1) por predefinição.

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

Personalizar o domínio

Por predefinição, os utilizadores veem o URL da instância do Cloud Run quando iniciam sessão. Para especificar um domínio personalizado:

  1. Siga os passos em 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. Aceda à página IAP na Google Cloud consola.

      Aceda à página de CIs

    2. Selecione o recurso protegido pelo IAP.

    3. No painel lateral, selecione o ícone Editar junto ao campo URL de início de sessão.

    4. Selecione Usar uma página de início de sessão alojada existente e escolha o seu domínio no menu pendente.

    5. Clique em Guardar.

Usar uma página de início de sessão para vários recursos de IAP

Pode proteger vários recursos de IAP através da mesma página de início de sessão. Isto reduz o trabalho associado à gestão de várias configurações.

Para reutilizar uma página de início de sessão:

  1. Siga os passos neste artigo para implementar a página de autenticação para o primeiro recurso protegido pelo IAP.

  2. Ative o IAP para o segundo recurso. Quando lhe for pedido que especifique uma página de início de sessão, selecione Vou fornecer a minha própria página e introduza o URL do serviço do Cloud Run como o URL.

  3. Volte a implementar o serviço do Cloud Run.

Resolução de problemas

Cookies de terceiros e criação de partições de armazenamento em navegadores

Para navegadores que desativam cookies de terceiros ou implementam a partição de armazenamento, a página de início de sessão ou a página de administração podem não funcionar corretamente. Para resolver este problema, faça o seguinte:

  1. Volte a implementar a página de início de sessão para usar a versão mais recente 1.0.1.

  2. Se usar a funcionalidade Personalizar a página de início de sessão, certifique-se de que authDomain está definido como o LOGIN_URL que a IAP criou. Em alternativa, pode definir o authDomain como PROJECT_ID.firebaseapp.com se o signInFlow estiver definido como popup.

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

    ou

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

O que se segue?