Hosting di una pagina di accesso con Cloud Run

Per utilizzare le identità esterne con Identity-Aware Proxy (IAP), la tua app deve avere una pagina di accesso. IAP reindirizzerà gli utenti a questa pagina per l'autenticazione prima che possano accedere alle risorse protette.

Questo documento mostra come eseguire il deployment e personalizzare una pagina di accesso predefinita utilizzando Cloud Run. Questo è il modo più rapido per iniziare a utilizzare le identità esterne e non richiede la scrittura di codice.

Puoi anche creare una pagina di accesso autonomamente. Creare una pagina personalizzata è più difficile, ma aumenta il controllo sul flusso di autenticazione e sull'esperienza utente. Per saperne di più, consulta Creare una pagina di accesso con FirebaseUI e Creare una pagina di accesso personalizzata.

Limitazioni della pagina di accesso

Non puoi utilizzare la pagina di accesso predefinita se nel tuo progetto è attiva la protezione di enumerazione email.

Se nel progetto è attiva la protezione di enumerazione email, disattiva email-enumeration-protection prima di continuare con le procedure descritte in questo documento.

Prima di iniziare

  • Abilita l'API Compute Engine.

    Abilita l'API Compute Engine

  • Attiva le identità esterne e seleziona l'opzione Crea una pagina di accesso per me durante la configurazione. In questo modo, Cloud Run e FirebaseUI possono creare una pagina di accesso per te.

  • Assicurati che l'account di servizio utilizzato da Cloud Run, PROJECT_NUMBER-compute@developer.gserviceaccount.com, abbia i seguenti ruoli predefiniti:

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

Impostazione dell'URI di reindirizzamento autorizzato per i provider di Identity Platform

Se utilizzi provider Identity Platform che richiedono il reindirizzamento all'accesso (reindirizzamento alla pagina di accesso dell'IdP esterno). Devi aggiungere l'URL della pagina di accesso ospitata come URL di reindirizzamento autorizzato nella configurazione del provider.

Ad esempio, per un fornitore Google, devi eseguire le seguenti operazioni:

  1. Copia l'URL di accesso dopo aver selezionato l'applicazione protetta da IAP.

  2. Nella console Google Cloud, vai alla pagina Credenziali.

    Vai a Credenziali

  3. Aggiungi LOGIN_URL/__/auth/handler come uno degli URI di reindirizzamento autorizzati per il client OAuth 2.0 della tua app. Seleziona lo stesso ID client OAuth utilizzato per configurare il provider Google.

Per altri provider SAML e OIDC, esegui la stessa operazione aggiungendo LOGIN_URL/__/auth/handler come URI di reindirizzamento autorizzato o URL ACS.

Test della pagina di accesso

La pagina di accesso iniziale creata da IAP è completamente funzionale. Per testarlo:

  1. Vai a una risorsa protetta da IAP. Dovresti essere reindirizzato automaticamente alla pagina di accesso.

  2. Seleziona un tenant e un provider con cui accedere. Se non visualizzi alcun tenant o fornitore, assicurati di averne configurato uno utilizzando Identity Platform.

  3. Accedi con le tue credenziali.

Dovresti essere reindirizzato alla risorsa protetta.

Personalizzazione della pagina di accesso

Puoi personalizzare la pagina di accesso utilizzando un file di configurazione JSON. Ecco alcune opzioni:

  • Aggiunta di un'intestazione e di un logo alla pagina di accesso.
  • Specifica i tenant e i provider disponibili.
  • Personalizzazione delle icone e dello stile di ogni pulsante di tenant e provider.
  • Aggiunta di link alle norme sulla privacy e ai Termini di servizio dell'app.

Le sezioni seguenti spiegano come accedere e aggiornare il file di configurazione JSON.

Ottenere un token di accesso

Per amministrare la pagina di accesso, devi disporre di un token di accesso Google. Il modo più semplice per ottenerne uno è attivare Google come provider per Identity Platform. Se la tua app utilizza già Google come provider di identità, puoi saltare questa sezione.

  1. Vai alla pagina Provider di Identity Platform nella console Google Cloud.

    Vai alla pagina Provider di Identity Platform

  2. Fai clic su Aggiungi un fornitore.

  3. Seleziona Google dall'elenco dei provider.

  4. Configura l'ID client web e il client secret web:

    1. Nella console Google Cloud, vai alla pagina Credenziali.

      Vai a Credenziali

    2. Utilizza un client OAuth 2.0 esistente o creane uno nuovo. Configura Client ID e Client secret su ID client web e Client secret web. Aggiungi LOGIN_URL/__/auth/handler come uno degli URI di reindirizzamento autorizzati per il client OAuth 2.0. LOGIN_URL è l'URL di accesso creato da IAP dopo aver selezionato l'opzione Crea una pagina di accesso per me. Puoi trovarlo nella pagina IAP della console Google Cloud, selezionando la risorsa protetta da IAP.

  5. Fai clic su Salva in entrambe le pagine.

Accedere al pannello di amministrazione

La configurazione JSON per la pagina di accesso ospitata da Cloud Run nel riquadro LOGIN_URL/admin. I passaggi seguenti mostrano come accedere al riquadro. Tieni presente che ti servirà il ruolo Amministratore archiviazione (roles/storage.admin).

  1. Vai alla pagina IAP nella console Google Cloud.

    Vai alla pagina IAP

  2. Seleziona la risorsa dall'elenco.

  3. Avvia l'URL elencato in Personalizza pagina nel riquadro delle informazioni. Dovrebbe avere un aspetto simile a questo: https://servicename-xyz-uc.a.run.app/admin.

  4. Accedi con lo stesso Account Google utilizzato per configurare IAP. Viene visualizzato un editor di testo contenente il file di configurazione JSON.

Modifica della configurazione

Lo schema di configurazione della pagina di accesso si basa su FirebaseUI, e ne eredita molte proprietà. Anziché utilizzare LOGIN_URL creato dall'IAP come authDomain predefinito, puoi utilizzare PROJECT_ID.firebaseapp.com.

Se vuoi utilizzare PROJECT_ID.firebaseapp.com come authDomain, cambia signInFlow in popup per evitare il problema di accesso allo spazio di archiviazione di terze parti sui principali browser(consulta le best practice per l'utilizzo di signInWithRedirect sui browser che bloccano l'accesso allo spazio di archiviazione di terze parti). Inoltre, segui le istruzioni riportate in Impostazione dell'URI di reindirizzamento autorizzato per i fornitori di Identity Platform per aggiungere PROJECT_ID.firebaseapp.com/__/auth/handler come uno degli URI di reindirizzamento autorizzati o degli URL ACS per il fornitore di Identity Platform con cui gli utenti accederanno.

Il seguente codice mostra un'esempio di configurazione con tre tenant:

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

Per un elenco completo delle proprietà disponibili, consulta la documentazione di riferimento.

Sostituzione del CSS

Puoi utilizzare la proprietà styleUrl per specificare un file CSS personalizzato. Gli stili in questo file sostituiranno il CSS predefinito. Il file deve essere accessibile pubblicamente tramite HTTPS (ad esempio, ospitato in un bucket Cloud Storage).

L'esempio seguente mostra l'override del CSS predefinito:

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

Esegui nuovamente il deployment dell'istanza Cloud Run

In alcuni casi, potrebbe essere necessario eseguire nuovamente il deployment dell'istanza Cloud Run che ospita la pagina di accesso. Ecco alcuni scenari di esempio:

  • Aggiungere, modificare o rimuovere fornitori di identità
  • Modifica delle configurazioni del tenant
  • Imposta le variabili di ambiente
  • Aggiornamento dell'immagine del contenitore alla versione più recente

L'aggiornamento e il ricoinvolgimento regolari dell'immagine del contenitore ti assicurano di disporre delle correzioni di bug e delle patch di sicurezza più recenti. Puoi visualizzare l'elenco delle modifiche tra le versioni su GitHub.

Puoi ottenere la versione corrente del contenitore di cui è stato eseguito il deployment utilizzando l'endpoint /versionz. Ad esempio:

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

Per eseguire nuovamente il deployment dell'istanza Cloud Run:

  1. Vai alla pagina Cloud Run nella console Google Cloud.

    Vai alla pagina Cloud Run

  2. Seleziona l'istanza che ospita la pagina di accesso.

  3. Fai clic su Modifica ed esegui il deployment di una nuova revisione.

  4. Se vuoi, specifica le impostazioni avanzate per la revisione o aggiungi una variabile di ambiente facendo clic sulla scheda Variabili e secret.

  5. Fai clic su Esegui il deployment.

Opzioni avanzate

Personalizzazione della pagina di accesso tramite programmazione

Oltre a utilizzare la console /admin, puoi aggiornare la configurazione JSON tramite programmazione.

Per ottenere la configurazione corrente, utilizza l'endpoint /get_admin_config. Ad esempio:

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

Per aggiornare la configurazione, utilizza /set_admin_config. Ad esempio:

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

Entrambe le chiamate REST richiedono l'ambito https://www.googleapis.com/auth/devstorage.read_write e un token OAuth valido deve essere allegato all'intestazione Authorization.

Imposta le variabili di ambiente

Puoi impostare variabili di ambiente sull'istanza Cloud Run per personalizzare le impostazioni avanzate. La tabella seguente elenca le variabili disponibili:

Variabile Descrizione
DEBUG_CONSOLE Un valore booleano (0 o 1) che indica se registrare o meno tutti gli errori e i dettagli delle richieste di rete. I dati sensibili non verranno registrati. Disattivata (0) per impostazione predefinita.
UI_CONFIG Una stringa contenente la configurazione JSON per la pagina di accesso. L'utilizzo di questa variabile anziché del riquadro /admin evita la lettura e la scrittura su Cloud Storage quando si accede alla configurazione. Le configurazioni non valide vengono ignorate. L'utilizzo del riquadro /admin per convalidare il codice JSON prima di impostare questa variabile può contribuire a ridurre al minimo gli errori di sintassi.
GCS_BUCKET_NAME Una stringa che sostituisce il bucket Cloud Storage predefinito utilizzato per archiviare la configurazione JSON. Il file si chiama config.json e la posizione predefinita è gcip-iap-bucket-[CLOUD-RUN-SERVICE-NAME]-[PROJECT-NUMBER].
ALLOW_ADMIN Un valore booleano (0 o 1) che indica se consentire o meno l'accesso al riquadro di configurazione /admin. Abilitata (1) per impostazione predefinita.

Devi eseguire il deployment di una nuova revisione dell'istanza Cloud Run dopo aver aggiornato le variabili prima che le modifiche vengano applicate. Per scoprire di più sulle variabili di ambiente, consulta la documentazione di Cloud Run.

Personalizzazione del dominio

Per impostazione predefinita, gli utenti vedranno l'URL dell'istanza Cloud Run quando accedono. Per specificare un dominio personalizzato:

  1. Segui i passaggi descritti in Mappatura di domini personalizzati per impostare un dominio personalizzato per l'istanza Cloud Run.

  2. Configura IAP in modo che utilizzi il nuovo URL di autenticazione:

    1. Vai alla pagina IAP nella console Google Cloud.

      Vai alla pagina IAP

    2. Seleziona la risorsa protetta da IAP.

    3. Nel riquadro laterale, seleziona l'icona Modifica accanto al campo URL di accesso.

    4. Seleziona Usa una pagina di accesso ospitata esistente e scegli il tuo dominio dal menu a discesa.

    5. Fai clic su Salva.

Utilizzo di una pagina di accesso per più risorse IAP

Puoi proteggere più risorse IAP utilizzando la stessa pagina di accesso. In questo modo si riduce il lavoro associato alla gestione di più configurazioni.

Per riutilizzare una pagina di accesso:

  1. Segui i passaggi descritti in questo articolo per implementare la pagina di autenticazione per la prima risorsa protetta da IAP.

  2. Attivare IAP per la seconda risorsa. Quando ti viene chiesto di specificare una pagina di accesso, seleziona Fornirò il mio URL e inserisci l'URL del servizio Cloud Run come URL.

  3. Esegui nuovamente il deployment del servizio Cloud Run.

Risoluzione dei problemi

Cookie di terze parti e partizionamento dello spazio di archiviazione nei browser

Per i browser che disattivano i cookie di terze parti o implementano il partizionamento dello spazio di archiviazione, la pagina di accesso o la pagina di amministrazione potrebbe non funzionare correttamente. Per risolvere il problema:

  1. Esegui nuovamente il deployment della pagina di accesso per utilizzare la versione 1.0.1 più recente.

  2. Se utilizzi la funzionalità Personalizzazione della pagina di accesso, assicurati che authDomain sia impostato come LOGIN_URL creato da IAP. In alternativa, puoi impostare authDomain su PROJECT_ID.firebaseapp.com se signInFlow è impostato su popup.

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

    o

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

Passaggi successivi