Héberger une page de connexion avec Cloud Run

Pour utiliser des identités externes avec Identity Aware Proxy (IAP), votre application doit disposer d'une page de connexion. IAP redirige les utilisateurs vers cette page afin qu'ils puissent s'authentifier et ainsi accéder à des ressources sécurisées.

Ce document vous explique comment déployer et personnaliser une page de connexion prédéfinie à l'aide de Cloud Run. Il s'agit du moyen le plus rapide pour commencer à utiliser des identités externes, et ne nécessite pas d'écriture de code.

Vous pouvez également créer vous-même une page de connexion. Créer votre propre page est plus compliqué, mais cela vous permet de mieux contrôler le flux d'authentification et l'expérience utilisateur. Pour en savoir plus, consultez les pages Créer une page de connexion avec FirebaseUI et Créer une page de connexion personnalisée.

Limites de la page de connexion

Vous ne pouvez pas utiliser la page de connexion prédéfinie si la protection contre l'énumération des adresses e-mail est activée pour votre projet.

Si la protection contre l'énumération d'adresses e-mail est activée pour votre projet, désactivez email-enumeration-protection avant de continuer avec les procédures de ce document.

Avant de commencer

  • Activez l'API Compute Engine.

    Activer l'API Compute Engine

  • Activez les identités externes, puis sélectionnez l'option Créer une page de connexion pour moi lors de la configuration. Cela permet à Cloud Run et à FirebaseUI de créer une page de connexion pour vous.

  • Assurez-vous que le compte de service utilisé par Cloud Run, PROJECT_NUMBER-compute@developer.gserviceaccount.com, dispose des rôles prédéfinis suivants:

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

Définir l'URI de redirection autorisé pour les fournisseurs Identity Platform

Si vous utilisez des fournisseurs Identity Platform qui nécessitent une redirection de connexion (redirection vers la page de connexion du fournisseur d'identité externe). Vous devez ajouter l'URL de la page de connexion hébergée en tant qu'URL de redirection autorisée dans la configuration de votre fournisseur.

Par exemple, pour un fournisseur Google, procédez comme suit:

  1. Copiez l'URL de connexion après avoir sélectionné votre application sécurisée par IAP.

  2. Dans la console Google Cloud, accédez à la page Identifiants.

    Accéder à "Identifiants"

  3. Ajoutez LOGIN_URL/__/auth/handler comme l'un des URI de redirection autorisés pour le client OAuth 2.0 de votre application. Sélectionnez le même ID client OAuth que celui que vous avez utilisé lors de la configuration du fournisseur Google.

Pour les autres fournisseurs SAML et OIDC, procédez de la même manière en ajoutant LOGIN_URL/__/auth/handler comme URI de redirection autorisé ou URL ACS.

Tester la page de connexion

La page de connexion initiale créée par IAP est entièrement opérationnelle. Pour la tester :

  1. Accédez à une ressource protégée par IAP. Vous devriez être redirigé automatiquement vers la page de connexion.

  2. Sélectionnez un locataire et un fournisseur avec lesquels vous connecter. Si aucun locataire ni aucun fournisseur n'est répertorié, vérifiez que vous en avez configuré un à l'aide d'Identity Platform.

  3. Connectez-vous avec vos identifiants.

Vous devriez être redirigé vers la ressource protégée.

Personnaliser la page de connexion

Vous pouvez personnaliser la page de connexion à l'aide d'un fichier de configuration JSON. Vous disposez, par exemple, des possibilités suivantes :

  • Ajout d'un en-tête et d'un logo à la page de connexion.
  • Spécifier les locataires et les fournisseurs disponibles.
  • Personnaliser les icônes et le style de chaque bouton locataire et fournisseur.
  • Ajouter des liens vers les règles de confidentialité et les conditions d'utilisation de votre application.

Les sections suivantes expliquent comment accéder au fichier de configuration JSON et le mettre à jour.

Obtenir un jeton d'accès

Pour administrer la page de connexion, vous avez besoin d'un jeton d'accès Google. Le moyen le plus simple d'en obtenir un consiste à activer Google en tant que fournisseur pour Identity Platform. Si votre application utilise déjà Google comme fournisseur d'identité, vous pouvez ignorer cette section.

  1. Accédez à la page Fournisseurs Identity Platform dans la console Google Cloud.

    Accéder à la page "Fournisseurs Identity Platform"

  2. Cliquez sur Ajouter un fournisseur.

  3. Sélectionnez Google dans la liste des fournisseurs.

  4. Configurez l'ID du client Web et le code secret du client Web :

    1. Dans la console Google Cloud, accédez à la page Identifiants.

      Accéder à "Identifiants"

    2. Utilisez un client OAuth 2.0 existant ou créez-en un. Configurez Client ID et Client secret sur ID client Web et Code secret du client Web. Ajoutez LOGIN_URL/__/auth/handler comme l'un des URI de redirection autorisés pour le client OAuth 2.0. LOGIN_URL correspond à l'URL de connexion créée par IAP après avoir sélectionné l'option Créer une page de connexion pour moi. Vous le trouverez sur la page "IAP" de la console Google Cloud, en sélectionnant la ressource sécurisée par IAP.

  5. Cliquez sur Enregistrer sur les deux pages.

Se connecter au panneau d'administration

Configuration JSON de la page de connexion hébergée par Cloud Run dans le panneau LOGIN_URL/admin. Pour accéder au panneau, procédez comme suit. Notez que vous aurez besoin du rôle Administrateur de l'espace de stockage (roles/storage.admin).

  1. Accédez à la page IAP dans la console Google Cloud.

    Accéder à la page "IAP"

  2. Sélectionnez votre ressource dans la liste.

  3. Lancez l'URL répertoriée sous Personnaliser la page dans le panneau d'informations. Elle doit se présenter comme ceci : https://servicename-xyz-uc.a.run.app/admin.

  4. Connectez-vous avec le compte Google que vous avez utilisé pour configurer IAP. Le fichier de configuration JSON s'affiche dans un éditeur de texte.

Modifier la configuration

Le schéma de configuration de la page de connexion est basé sur FirebaseUI et hérite d'un grand nombre de ses propriétés. Au lieu d'utiliser le LOGIN_URL créé par l'IAP comme authDomain par défaut, vous pouvez utiliser PROJECT_ID.firebaseapp.com.

Si vous souhaitez utiliser PROJECT_ID.firebaseapp.com comme authDomain, remplacez signInFlow par popup pour éviter les problèmes d'accès au stockage tiers dans les principaux navigateurs(voir la section Bonnes pratiques pour utiliser signInWithRedirect dans les navigateurs qui bloquent l'accès au stockage tiers). Suivez également les instructions de la section Définir un URI de redirection autorisé pour les fournisseurs Identity Platform pour ajouter PROJECT_ID.firebaseapp.com/__/auth/handler comme l'un des URI de redirection autorisés ou des URL ACS du fournisseur Identity Platform avec lequel les utilisateurs se connecteront.

Le code suivant montre un exemple de configuration avec trois locataires:

{
  "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"
        }
      },
    }
  }
}

Pour obtenir la liste complète des propriétés disponibles, consultez la documentation de référence.

Ignorer CSS

Vous pouvez utiliser la propriété styleUrl pour spécifier un fichier CSS personnalisé. Les styles de ce fichier remplacent la feuille de style CSS par défaut. Le fichier doit être accessible publiquement via HTTPS (par exemple, hébergé dans un bucket Cloud Storage).

L'exemple suivant montre comment remplacer le CSS par défaut :

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

Redéployer l'instance Cloud Run

Dans certains cas, il peut être judicieux de redéployer l'instance Cloud Run qui héberge la page de connexion. Exemples de scénarios :

  • Ajouter, modifier ou supprimer des fournisseurs d'identité
  • Modifier les configurations de locataires
  • Définir des variables d'environnement
  • Mettre à jour l'image du conteneur vers la dernière version

La mise à jour et le redéploiements réguliers de l'image du conteneur vous permettent de bénéficier des dernières corrections de bug et des derniers correctifs de sécurité. Vous pouvez consulter la liste des modifications entre les versions sur GitHub.

Vous pouvez obtenir la version actuelle du conteneur déployé à l'aide du point de terminaison /versionz. Exemple :

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

Pour redéployer l'instance Cloud Run, procédez comme suit :

  1. Accédez à la page Cloud Run de la console Google Cloud.

    Accéder à la page Cloud Run

  2. Sélectionnez l'instance hébergeant la page de connexion.

  3. Cliquez sur Modifier et déployer la nouvelle révision.

  4. Vous pouvez également spécifier des paramètres avancés pour la révision, ou ajouter une variable d'environnement en cliquant sur l'onglet Variables et secrets.

  5. Cliquez sur Déployer.

Options avancées

Personnaliser la page de connexion par programmation

En plus d'utiliser la console /admin, vous pouvez mettre à jour la configuration JSON par programmation.

Pour obtenir la configuration actuelle, utilisez le point de terminaison /get_admin_config. Exemple :

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

Pour mettre à jour la configuration, utilisez /set_admin_config. Exemple :

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

Les deux appels REST nécessitent le champ d'application https://www.googleapis.com/auth/devstorage.read_write. Un jeton OAuth valide doit être associé à l'en-tête Authorization.

Définir des variables d'environnement

Vous pouvez définir des variables d'environnement sur l'instance Cloud Run pour personnaliser les paramètres avancés. Le tableau suivant répertorie les variables disponibles :

Variable Description
DEBUG_CONSOLE Valeur booléenne (0 ou 1) indiquant s'il faut consigner toutes les erreurs et tous les détails de la requête réseau. Les données sensibles ne seront pas consignées. Elle est désactivée (0) par défaut.
UI_CONFIG Chaîne contenant la configuration JSON de la page de connexion. L'utilisation de cette variable au lieu du panneau /admin évite la lecture et l'écriture dans un bucket Cloud Storage lors de l'accès à la configuration. Les configurations non valides sont ignorées. L'utilisation du panneau /admin pour valider votre fichier JSON avant de définir cette variable peut contribuer à réduire les erreurs de syntaxe.
GCS_BUCKET_NAME Chaîne remplaçant le bucket Cloud Storage par défaut utilisé pour stocker la configuration JSON. Le fichier est nommé config.json et son emplacement par défaut est gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN Valeur booléenne (0 ou 1) indiquant s'il faut autoriser l'accès au panneau de configuration /admin. Activé par défaut (1)

Vous devrez déployer une nouvelle révision de l'instance Cloud Run après la mise à jour des variables pour que les modifications prennent effet. Pour en savoir plus sur les variables d'environnement, consultez la documentation Cloud Run.

Personnaliser le domaine

Par défaut, les utilisateurs voient l'URL de l'instance Cloud Run lorsqu'ils se connectent. Pour spécifier un domaine personnalisé, procédez comme suit :

  1. Suivez les étapes décrites dans la section Mapper des domaines personnalisés pour définir un domaine personnalisé pour l'instance Cloud Run.

  2. Configurez IAP pour utiliser la nouvelle URL d'authentification :

    1. Accédez à la page IAP dans la console Google Cloud.

      Accéder à la page "IAP"

    2. Sélectionnez la ressource protégée par IAP.

    3. Dans le panneau latéral, sélectionnez l'icône Modifier à côté du champ URL de connexion.

    4. Sélectionnez Utiliser une page de connexion hébergée existante, puis choisissez votre domaine dans le menu déroulant.

    5. Cliquez sur Save.

Utiliser une page de connexion pour plusieurs ressources IAP

Vous pouvez protéger plusieurs ressources IAP à l'aide de la même page de connexion. Cela réduit le travail associé à la gestion de plusieurs configurations.

Pour réutiliser une page de connexion :

  1. Suivez les étapes décrites de cet article pour déployer la page d'authentification de la première ressource protégée par IAP.

  2. Activez IAP pour la deuxième ressource. Lorsque vous êtes invité à spécifier une page de connexion, sélectionnez Je fournis ma propre page, puis, dans le champ URL, saisissez l'URL du service Cloud Run.

  3. Redéployez le service Cloud Run.

Dépannage

Cookies tiers et partitionnement du stockage dans les navigateurs

Pour les navigateurs qui désactivent les cookies tiers ou implémentent la partitionnement de l'espace de stockage, la page de connexion ou la page d'administration peuvent ne pas fonctionner correctement. Pour résoudre ce problème, procédez comme suit :

  1. Redéployer la page de connexion pour utiliser la dernière version 1.0.1.

  2. Si vous utilisez la fonctionnalité Personnaliser la page de connexion, assurez-vous que authDomain est défini comme LOGIN_URL créé par l'API IAP. Vous pouvez également définir authDomain sur PROJECT_ID.firebaseapp.com si signInFlow est défini sur popup.

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

    ou

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

Étape suivante