Aloja una página de acceso con Cloud Run

Tu app necesita una página de acceso para usar identidades externas con Identity-Aware Proxy (IAP). IAP redireccionará a los usuarios a esta página para que se autentiquen antes de que puedan acceder a los recursos seguros.

En este documento, se muestra cómo implementar y personalizar una página de acceso ya compilada mediante Cloud Run. Esta es la forma más rápida de comenzar a usar las identidades externas y no es necesario que escribas código.

También puedes compilar una página de acceso por tu cuenta. Crear tu propia página es más difícil, pero aumenta el control sobre el flujo de autenticación y la experiencia del usuario. Para obtener más información, consulta Crea una página de acceso con FirebaseUI y Crea una página de acceso personalizada.

Limitaciones de la página de acceso

No puedes usar la página de acceso precompilada si tu proyecto tiene habilitada la protección contra la enumeración de correo electrónico.

Si tu proyecto tiene habilitada la protección contra la enumeración de correo electrónico, inhabilita email-enumeration-protection antes de continuar con los procedimientos de este documento.

Antes de comenzar

  • Habilita la API de Compute Engine.

    Habilitar la API de Compute Engine

  • Habilita identidades externas y selecciona la opción Crear una página de acceso para mí durante la configuración. Esto permite que Cloud Run y FirebaseUI creen una página de acceso por ti.

  • Asegúrate de que la cuenta de servicio que usa Cloud Run, PROJECT_NUMBER-compute@developer.gserviceaccount.com, tenga los siguientes roles predefinidos:

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

Cómo configurar el URI de redireccionamiento autorizado para proveedores de Identity Platform

Si usas proveedores de Identity Platform que requieren un redireccionamiento de acceso (redireccionamiento a la página de acceso del IdP externo) Debes agregar la URL de la página de acceso alojada como una URL de redireccionamiento autorizada en la configuración de tu proveedor.

Por ejemplo, para un proveedor de Google, debes hacer lo siguiente:

  1. Copia la URL de acceso después de seleccionar tu aplicación protegida con IAP.

  2. En la consola de Google Cloud, ve a la página Credenciales.

    Ir a Credenciales

  3. Agrega LOGIN_URL/__/auth/handler como uno de los URIs de redireccionamiento autorizados para el cliente de OAuth 2.0 de tu app. Selecciona el mismo ID de cliente de OAuth que usaste cuando configuraste el proveedor de Google.

Para otros proveedores de SAML y OIDC, haz lo mismo y agrega LOGIN_URL/__/auth/handler como el URI de redireccionamiento autorizado o la URL de ACS.

Prueba la página de acceso

La página de acceso inicial que creó IAP es completamente funcional. Para probarla, haz lo siguiente:

  1. Navega a un recurso protegido por IAP. El sistema te debería redireccionar automáticamente a la página de acceso.

  2. Selecciona un usuario y un proveedor para acceder. Si no ves ningún usuario o proveedor en la lista, asegúrate de haber configurado uno con Identity Platform.

  3. Accede con tus credenciales.

Se te debería redireccionar al recurso protegido.

Personaliza la página de acceso

Puedes personalizar la página de acceso mediante un archivo de configuración JSON. Estas son algunas opciones:

  • Agrega un encabezado y un logotipo a la página de acceso.
  • Especifica los usuarios y proveedores disponibles.
  • Personaliza los íconos y el estilo de cada botón de proveedor y usuario.
  • Agrega vínculos a la política de privacidad y a las Condiciones del Servicio de tu app.

En las siguientes secciones, se explica cómo acceder al archivo de configuración JSON y actualizarlo.

Obtén un token de acceso

Para administrar la página de acceso, necesitas un token de acceso de Google. La manera más fácil de obtener uno es habilitar Google como proveedor para Identity Platform. Si tu app ya usa Google como proveedor de identidad, puedes omitir esta sección.

  1. Ve a la página Proveedores de Identity Platform en la console de Google Cloud.

    Ir a la página Proveedores de Identity Platform

  2. Haz clic en Agregar un proveedor.

  3. Selecciona Google de la lista de proveedores.

  4. Configura el ID de cliente web y el secreto del cliente web:

    1. En la consola de Google Cloud, ve a la página Credenciales.

      Ir a Credenciales

    2. Usa un cliente de OAuth 2.0 existente o crea uno nuevo. Configura Client ID y Client secret como ID de cliente web y Secreto del cliente web. Agrega LOGIN_URL/__/auth/handler como uno de los URIs de redireccionamiento autorizados para el cliente de OAuth 2.0. LOGIN_URL es la URL de acceso que crea IAP después de seleccionar la opción Crear una página de acceso para mí. Puedes encontrarlo en la página de IAP de la consola de Google Cloud. Para ello, selecciona el recurso protegido por IAP.

  5. En ambas páginas, haga clic en Guardar.

Accede al panel de administración

La configuración de JSON para la página de acceso alojada por Cloud Run en el panel LOGIN_URL/admin. En los siguientes pasos, se muestra cómo acceder al panel. Ten en cuenta que necesitarás el rol de administrador de almacenamiento (roles/storage.admin).

  1. Ve a la página IAP en la consola de Google Cloud.

    Ir a la página de IAP

  2. Selecciona tu recurso de la lista.

  3. Inicia la URL que se enumera en Personalizar página en el panel de información. Debería tener el formato https://servicename-xyz-uc.a.run.app/admin.

  4. Accede con la misma cuenta de Google que usaste para configurar IAP. Aparecerá un editor de texto que contiene el archivo de configuración JSON.

Modifica la configuración

El esquema de configuración para la página de acceso se basa en FirebaseUI y hereda muchas de sus propiedades. En lugar de usar el LOGIN_URL creado por el IAP como el authDomain predeterminado, puedes usar PROJECT_ID.firebaseapp.com.

Si quieres usar PROJECT_ID.firebaseapp.com como authDomain, cambia signInFlow a popup para evitar problemas de acceso al almacenamiento de terceros en los navegadores principales(consulta Prácticas recomendadas para usar signInWithRedirect en navegadores que bloquean el acceso al almacenamiento de terceros). Además, sigue las instrucciones que se indican en Configuración del URI de redireccionamiento autorizado para proveedores de Identity Platform para agregar PROJECT_ID.firebaseapp.com/__/auth/handler como uno de los URI de redireccionamiento autorizados o las URLs de ACS del proveedor de Identity Platform con el que los usuarios accederán.

En el siguiente código, se muestra un ejemplo de configuración con tres usuarios:

{
  "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 obtener una lista completa de las propiedades disponibles, consulta la documentación de referencia.

Anula un CSS

Puedes usar la propiedad styleUrl para especificar un archivo de CSS personalizado. Los estilos de este archivo anularán el CSS predeterminado. El archivo debe ser accesible de forma pública mediante HTTPS (por ejemplo, alojado en un bucket de Cloud Storage).

En el siguiente ejemplo, se muestra la anulación del CSS predeterminado:

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

Vuelve a implementar la instancia de Cloud Run

En algunos casos, es posible que desees volver a implementar la instancia de Cloud Run que aloja la página de acceso. Algunos ejemplos de situaciones son los siguientes:

  • Agregar, modificar o quitar proveedores de identidad
  • Modificar las configuraciones de usuario
  • Configura variables de entorno
  • Actualizar la imagen de contenedor a la versión más reciente

Actualizar y volver a implementar la imagen del contenedor con regularidad garantiza que tengas las correcciones de errores y los parches de seguridad más recientes. Puedes ver la lista de cambios entre las versiones en GitHub.

Puedes obtener la versión actual del contenedor implementado mediante el extremo /versionz. Por ejemplo:

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

Para volver a implementar la instancia de Cloud Run, haz lo siguiente:

  1. Ve a la página de Cloud Run en la consola de Google Cloud.

    Ir a la página de Cloud Run

  2. Selecciona la instancia que aloja la página de acceso.

  3. Haz clic en Editar e implementar nueva revisión.

  4. De manera opcional, puedes especificar la configuración avanzada para la revisión o agregar una variable de entorno mediante un clic en la pestaña Variables y secretos.

  5. Haz clic en Implementar.

Opciones avanzadas

Personaliza la página de acceso de manera programática

Además de usar la consola /admin, puedes actualizar la configuración JSON de manera programática.

Para obtener la configuración actual, usa el extremo /get_admin_config. Por ejemplo:

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

Para actualizar la configuración, usa /set_admin_config. Por ejemplo:

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 llamadas de REST requieren el permiso https://www.googleapis.com/auth/devstorage.read_write y se debe adjuntar un token de OAuth válido al encabezado Authorization.

Configura variables de entorno

Puedes establecer variables de entorno en la instancia de Cloud Run para personalizar la configuración avanzada. En la siguiente tabla, se enumeran las variables disponibles:

Variable Descripción
DEBUG_CONSOLE Un valor booleano (0 o 1) que indica si se deben registrar todos los errores y los detalles de la solicitud de red. No se registrarán los datos sensibles. Está inhabilitado (0) de forma predeterminada.
UI_CONFIG Es una string que contiene la configuración JSON para la página de acceso. Usar esta variable en lugar del panel /admin evita la lectura y la escritura en un Cloud Storage cuando se accede a la configuración. Se ignoran las configuraciones que no son válidas. Usar el panel /admin para validar tu JSON antes de configurar esta variable puede ayudar a minimizar los errores de sintaxis.
GCS_BUCKET_NAME Es una string que anula el bucket de Cloud Storage predeterminado que se usa para almacenar la configuración JSON. El archivo se llama config.json y la ubicación predeterminada es gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN Es un valor booleano (0 o 1) que indica si se debe permitir el acceso al panel de configuración /admin. Está habilitado (1) de forma predeterminada.

Deberás implementar una revisión nueva de la instancia de Cloud Run después de actualizar las variables y antes de que se apliquen los cambios. Para obtener más información sobre las variables de entorno, consulta la documentación de Cloud Run.

Personaliza el dominio

De forma predeterminada, los usuarios verán la URL de la instancia de Cloud Run cuando accedan. Para especificar un dominio personalizado en su lugar, haz lo siguiente:

  1. Sigue los pasos que se indican en Asignación de dominios personalizados a fin de configurar un dominio personalizado para la instancia de Cloud Run.

  2. Configura IAP para usar la nueva URL de autenticación:

    1. Ve a la página IAP en la consola de Google Cloud.

      Ir a la página de IAP

    2. Selecciona el recurso protegido por IAP.

    3. En el panel lateral, selecciona el ícono Editar junto al campo URL de acceso.

    4. Selecciona Usa una página de acceso alojada existente y elige tu dominio en el menú desplegable.

    5. Haga clic en Save.

Usa una página de acceso para varios recursos de IAP

Puedes proteger varios recursos de IAP con la misma página de acceso. Esto reduce el trabajo asociado con la administración de varias configuraciones.

Para volver a usar una página de acceso, haz lo siguiente:

  1. Sigue los pasos de este artículo para implementar la página de autenticación del primer recurso protegido por IAP.

  2. Habilita IAP para el segundo recurso. Cuando se te solicite que especifiques una página de acceso, selecciona Proporcionaré una propia e ingresa la URL del servicio de Cloud Run como la URL.

  3. Vuelve a implementar el servicio de Cloud Run.

Soluciona problemas

Cookies de terceros y partición de almacenamiento en navegadores

En el caso de los navegadores que inhabilitan las cookies de terceros o implementan la partición de almacenamiento, es posible que la página de acceso o la página del administrador no funcionen correctamente. Para solucionar este problema, haz lo siguiente:

  1. Volver a implementar la página de acceso para usar la versión 1.0.1 más reciente

  2. Si usas la función Cómo personalizar la página de acceso, asegúrate de que authDomain esté configurado como el LOGIN_URL que creó el IAP. Como alternativa, puedes establecer authDomain como PROJECT_ID.firebaseapp.com si signInFlow está configurado como popup.

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

    o

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

¿Qué sigue?