Autenticazione degli utenti con Go


App in esecuzione su piattaforme gestite da Google Cloud come App Engine possono evitare di gestire l'autenticazione degli utenti e la gestione delle sessioni utilizzando Identity-Aware Proxy (IAP) per controllarne l'accesso. IAP non può solo controllare l'accesso ma offre anche informazioni sugli utenti autenticati, inclusi l'indirizzo email e un identificatore permanente all'app sotto forma di nuove intestazioni HTTP.

Obiettivi

  • Richiedi agli utenti della tua app App Engine di eseguire l'autenticazione tramite utilizzando IAP.

  • Accedi agli utenti identità nell'app per visualizzare le informazioni .

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Installa Google Cloud CLI.
  4. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Installa Google Cloud CLI.
  7. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  8. Prepara l'ambiente di sviluppo.

Configurazione del progetto

  1. Nella finestra del terminale, clona il repository dell'app di esempio sulla tua macchina locale:

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
  2. Passa alla directory che contiene il codice di esempio:

    cd golang-samples/getting-started/authenticating-users

Contesto

Questo tutorial utilizza IAP per autenticare gli utenti. Questo è solo uno dei tanti possibili approcci. Per scoprire di più sui vari metodi per autenticare gli utenti, vedi Sezione Concetti di autenticazione.

L'app Hello user-email-address

L'app per questo tutorial è un'app Hello World minima di App Engine, con una caratteristica non tipica: invece di "Hello world" mostra "Ciao user-email-address", dove user-email-address è l'account autenticato all'indirizzo email dell'utente.

Questa funzionalità è possibile esaminando le informazioni autenticate che IAP aggiunge a ogni richiesta web che passa alla tua app. Esistono tre nuove intestazioni di richiesta aggiunte a ogni richiesta web che raggiunge la tua app. Le prime due intestazioni sono stringhe di testo normale che puoi utilizzare identificare l'utente. La terza intestazione è un oggetto firmato in modo crittografico con le stesse informazioni.

  • X-Goog-Authenticated-User-Email: l'indirizzo email di un utente lo identifica. Non memorizzare informazioni personali se la tua app può evitarle. Questa app non archiviare qualsiasi dato; ma lo restituisce all'utente.

  • X-Goog-Authenticated-User-Id: questo ID utente assegnato da Google non mostrare informazioni sull'utente, ma consente a un'app di sapere indica che un utente che ha eseguito l'accesso è lo stesso visualizzato in precedenza.

  • X-Goog-Iap-Jwt-Assertion: puoi configurare le app Google Cloud di accettare richieste web da altre applicazioni cloud, bypassando IAP, oltre alle richieste web su internet. Se un'app è così è possibile che queste richieste abbiano intestazioni falsificate. Invece di utilizzare una delle intestazioni di testo normale menzionate in precedenza, puoi utilizzare e verificare questa intestazione firmata in modo crittografico per controllare che le informazioni fornito da Google. Sia l'indirizzo email dell'utente sia un indirizzo ID utente sono disponibili come parte di questa intestazione firmata.

Se hai la certezza che l'app è configurata in modo che solo internet richieste web possono raggiungerlo e che nessuno può disattivare IAP servizio per l'app, per recuperare un ID utente univoco occorre una sola riga del codice:

userID := r.Header.Get("X-Goog-Authenticated-User-ID")

Tuttavia, un'app resiliente deve aspettarsi che qualcosa non va, ad esempio: problemi di configurazione o ambientali imprevisti, quindi consigliamo creando una funzione che utilizzi e verifica l'intestazione firmata in modo crittografico. La firma dell'intestazione non può essere contraffatta e, una volta verificata, può essere utilizzata per restituiscono l'identificazione.

Nozioni di base sul codice

Questa sezione spiega come funziona il codice. Se vuoi eseguire l'app, puoi passa alla sezione Deployment dell'app.

  • Il file go.mod definisce un Modulo Go e dai moduli da cui dipende.

    module github.com/GoogleCloudPlatform/golang-samples/getting-started/authenticating-users
    
    go 1.19
    
    require (
    	cloud.google.com/go/compute/metadata v0.3.0
    	github.com/golang-jwt/jwt v3.2.2+incompatible
    )
    
  • Il file app.yaml indica ad App Engine l'ambiente linguistico del tuo codice richiede.

    runtime: go112
  • L'app inizia importando i pacchetti e definendo una funzione main. La La funzione main registra un gestore di indici e avvia un server HTTP.

    
    // The authenticating-users program is a sample web server application that
    // extracts and verifies user identity data passed to it via Identity-Aware
    // Proxy.
    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"log"
    	"net/http"
    	"os"
    	"time"
    
    	"cloud.google.com/go/compute/metadata"
    	"github.com/golang-jwt/jwt"
    )
    
    // app holds the Cloud IAP certificates and audience field for this app, which
    // are needed to verify authentication headers set by Cloud IAP.
    type app struct {
    	certs map[string]string
    	aud   string
    }
    
    func main() {
    	a, err := newApp()
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	http.HandleFunc("/", a.index)
    
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    		log.Printf("Defaulting to port %s", port)
    	}
    
    	log.Printf("Listening on port %s", port)
    	if err := http.ListenAndServe(":"+port, nil); err != nil {
    		log.Fatal(err)
    	}
    }
    
    // newApp creates a new app, returning an error if either the Cloud IAP
    // certificates or the app's audience field cannot be obtained.
    func newApp() (*app, error) {
    	certs, err := certificates()
    	if err != nil {
    		return nil, err
    	}
    
    	aud, err := audience()
    	if err != nil {
    		return nil, err
    	}
    
    	a := &app{
    		certs: certs,
    		aud:   aud,
    	}
    	return a, nil
    }
    
  • La funzione index ottiene il valore dell'intestazione dell'asserzione JWT che IAP aggiunto dalla richiesta in arrivo e chiama Funzione validateAssertion per convalidare il valore firmato tramite crittografia. L'indirizzo email viene quindi utilizzato in una risposta web minima.

    
    // index responds to requests with our greeting.
    func (a *app) index(w http.ResponseWriter, r *http.Request) {
    	if r.URL.Path != "/" {
    		http.NotFound(w, r)
    		return
    	}
    
    	assertion := r.Header.Get("X-Goog-IAP-JWT-Assertion")
    	if assertion == "" {
    		fmt.Fprintln(w, "No Cloud IAP header found.")
    		return
    	}
    	email, _, err := validateAssertion(assertion, a.certs, a.aud)
    	if err != nil {
    		log.Println(err)
    		fmt.Fprintln(w, "Could not validate assertion. Check app logs.")
    		return
    	}
    
    	fmt.Fprintf(w, "Hello %s\n", email)
    }
    
  • La funzione validateAssertion convalida che l'asserzione è stata firmata correttamente e restituisce l'indirizzo email e l'ID utente associati.

    La convalida di un'asserzione JWT richiede la conoscenza dei certificati di chiave pubblica l'entità che ha firmato l'asserzione (in questo caso Google) e il pubblico a cui è destinata l'asserzione. Per un'app di App Engine, il pubblico è una stringa contenente le informazioni di identificazione del progetto Google Cloud. La funzione validateAssertion recupera i certificati dall'certs e la stringa di pubblico dalla funzione audience.

    
    // validateAssertion validates assertion was signed by Google and returns the
    // associated email and userID.
    func validateAssertion(assertion string, certs map[string]string, aud string) (email string, userID string, err error) {
    	token, err := jwt.Parse(assertion, func(token *jwt.Token) (interface{}, error) {
    		keyID := token.Header["kid"].(string)
    
    		_, ok := token.Method.(*jwt.SigningMethodECDSA)
    		if !ok {
    			return nil, fmt.Errorf("unexpected signing method: %q", token.Header["alg"])
    		}
    
    		cert := certs[keyID]
    		return jwt.ParseECPublicKeyFromPEM([]byte(cert))
    	})
    
    	if err != nil {
    		return "", "", err
    	}
    
    	claims, ok := token.Claims.(jwt.MapClaims)
    	if !ok {
    		return "", "", fmt.Errorf("could not extract claims (%T): %+v", token.Claims, token.Claims)
    	}
    
    	if claims["aud"].(string) != aud {
    		return "", "", fmt.Errorf("mismatched audience. aud field %q does not match %q", claims["aud"], aud)
    	}
    	return claims["email"].(string), claims["sub"].(string), nil
    }
    
  • Puoi cercare l'ID numerico e il nome del progetto Google Cloud e inserire nel codice sorgente, ma la funzione audience lo fa per eseguendo una query sul servizio di metadati standard reso disponibile dell'app App Engine. Poiché il servizio di metadati è esterno all'app del codice, il risultato viene salvato in una variabile globale che viene restituita senza dover cercare i metadati nelle chiamate successive.

    Il servizio metadati App Engine (e servizi di metadati simili per altri servizi di computing di Google Cloud) è simile a un sito web ed è interrogati da query web standard. Tuttavia, il servizio di metadati non è un sito esterno, ma una funzionalità interna che restituisce le informazioni richieste sull'app in esecuzione, quindi puoi usare http anziché https in sicurezza. richieste. Il servizio di metadati viene utilizzato per ottenere l'attuale dati di Google Cloud Identificatori necessari per definire il pubblico previsto dell'asserzione JWT.

    
    // audience returns the expected audience value for this service.
    func audience() (string, error) {
    	projectNumber, err := metadata.NumericProjectID()
    	if err != nil {
    		return "", fmt.Errorf("metadata.NumericProjectID: %w", err)
    	}
    
    	projectID, err := metadata.ProjectID()
    	if err != nil {
    		return "", fmt.Errorf("metadata.ProjectID: %w", err)
    	}
    
    	return "/projects/" + projectNumber + "/apps/" + projectID, nil
    }
    
  • La verifica di una firma digitale richiede il certificato di chiave pubblica di firmatario. Google mette a disposizione un sito web che restituisce tutti i dati certificati di chiave pubblica. Questi risultati vengono memorizzati nella cache nel caso in cui siano necessari di nuovo nella stessa istanza di app.

    
    // certificates returns Cloud IAP's cryptographic public keys.
    func certificates() (map[string]string, error) {
    	const url = "https://www.gstatic.com/iap/verify/public_key"
    	client := http.Client{
    		Timeout: 5 * time.Second,
    	}
    	resp, err := client.Get(url)
    	if err != nil {
    		return nil, fmt.Errorf("Get: %w", err)
    	}
    
    	var certs map[string]string
    	dec := json.NewDecoder(resp.Body)
    	if err := dec.Decode(&certs); err != nil {
    		return nil, fmt.Errorf("Decode: %w", err)
    	}
    
    	return certs, nil
    }
    

Deployment dell'app

Ora puoi eseguire il deployment dell'app e abilitare IAP per richiedere agli utenti devono eseguire l'autenticazione prima di poter accedere all'app.

  1. Nella finestra del terminale, vai alla directory contenente il file app.yaml, ed eseguire il deployment dell'app in App Engine:

    gcloud app deploy
    
  2. Quando richiesto, seleziona una regione nelle vicinanze.

  3. Quando ti viene chiesto se vuoi continuare l'operazione di deployment, inserisci Y.

    La tua app sarà attiva su internet entro pochi minuti.

  4. Visualizza l'app:

    gcloud app browse
    

    Nell'output, copia web-site-url, l'indirizzo web per l'app.

  5. In una finestra del browser, incolla web-site-url per aprire dell'app.

    Non viene visualizzata nessuna email perché non stai ancora utilizzando IAP, quindi no le informazioni utente vengono inviate all'app.

Abilita IAP

Ora che esiste un'istanza App Engine, puoi proteggerla IAP:

  1. Nella console Google Cloud, vai alla pagina Identity-Aware Proxy.

    Vai alla pagina Identity-Aware Proxy

  2. Poiché è la prima volta che attivi un'opzione di autenticazione per per questo progetto, viene visualizzato un messaggio che indica che devi configurare il consenso lo schermo prima di poter usare IAP.

    Fai clic su Configura schermata per il consenso.

  3. Nella scheda Schermata consenso OAuth della pagina Credenziali, completa nei seguenti campi:

    • Se il tuo account fa parte di un'organizzazione Google Workspace, seleziona Esterno e fai clic su Crea. All'inizio, l'app sarà disponibile soltanto per gli utenti che consentito in modo esplicito.

    • Nel campo Nome applicazione, inserisci IAP Example.

    • Nel campo Email assistenza, inserisci il tuo indirizzo email.

    • Nel campo Dominio autorizzato, inserisci la parte del nome host del URL, ad esempio iap-example-999999.uc.r.appspot.com. Premi il tasto Enter dopo aver inserito il nome host nel campo.

    • Nel campo Application home link (Link alla home page dell'applicazione), inserisci l'URL dell'app per ad esempio https://iap-example-999999.uc.r.appspot.com/.

    • Nel campo Riga Norme sulla privacy dell'applicazione, utilizza lo stesso URL della sezione link alla home page a scopo di test.

  4. Fai clic su Salva. Quando ti viene chiesto di creare le credenziali, puoi chiudere la finestra.

  5. Nella console Google Cloud, vai alla pagina Identity-Aware Proxy.

    Vai alla pagina Identity-Aware Proxy

  6. Per aggiornare la pagina, fai clic su Aggiorna . La mostra un elenco di risorse che puoi proteggere.

  7. Nella colonna IAP, fai clic per attivare IAP per l'app.

  8. Nel browser, visita di nuovo web-site-url.

  9. Invece della pagina web, c'è una schermata di accesso per autenticarvi. Quando esegui l'accesso, ti viene negato l'accesso perché IAP non Avere un elenco di utenti a cui consentire di accedere all'app.

Aggiungere utenti autorizzati all'app

  1. Nella console Google Cloud, vai alla pagina Identity-Aware Proxy.

    Vai alla pagina Identity-Aware Proxy

  2. Seleziona la casella di controllo in corrispondenza dell'app App Engine, quindi fai clic su Aggiungi entità.

  3. Inserisci allAuthenticatedUsers, quindi seleziona Ruolo Utente applicazione web con protezione IAP/IAP.

  4. Fai clic su Salva.

Ora qualsiasi utente che Google può autenticare può accedere all'app. Se vuoi, puoi limitare ulteriormente l'accesso aggiungendo solo una o più persone o gruppi come entità:

  • Qualsiasi indirizzo email Gmail o Google Workspace

  • L'indirizzo email di un gruppo Google

  • Un nome di dominio Google Workspace

Accedi all'app

  1. Nel browser, vai a web-site-url.

  2. Per aggiornare la pagina, fai clic su Aggiorna .

  3. Nella schermata di accesso, accedi con le tue credenziali Google.

    Nella pagina viene visualizzato il messaggio "Ciao user-email-address" pagina con .

    Se vedi ancora la stessa pagina di prima, potrebbe essersi verificato un problema relativo alla il browser non aggiorna completamente le nuove richieste ora che hai abilitato IAP. Chiudi tutte le finestre del browser, riaprile e riprova.

Concetti sull'autenticazione

Un'app può autenticare i propri utenti e limitare l'accesso in diversi modi solo agli utenti autorizzati. Metodi di autenticazione comuni per ridurre il livello di impegno dell'app sono elencate nelle sezioni che seguono.

Opzione Vantaggi Svantaggi
Autenticazione app
  • L'app può essere eseguita su qualsiasi piattaforma, con o senza connessione a internet
  • Gli utenti non devono utilizzare altri servizi per gestire l'autenticazione
  • L'app deve gestire le credenziali utente in modo sicuro e non deve essere divulgata
  • L'app deve conservare i dati delle sessioni degli utenti che hanno eseguito l'accesso
  • L'app deve fornire registrazione utente, modifiche della password e recupero della password
OAuth2
  • L'app può essere eseguita su qualsiasi piattaforma connessa a internet, incluso un workstation per sviluppatori
  • L'app non richiede la registrazione dell'utente, la modifica della password o la password di ripristino di emergenza.
  • Il rischio di divulgazione delle informazioni degli utenti è delegato ad un altro servizio
  • Nuove misure di sicurezza dell'accesso gestite al di fuori dell'app
  • Gli utenti devono registrarsi al servizio di identità
  • L'app deve conservare i dati delle sessioni degli utenti che hanno eseguito l'accesso
IAP
  • L'app non richiede codice per gestire gli utenti l'autenticazione o lo stato della sessione
  • L'app non ha credenziali utente che potrebbero essere violate
  • L'app può essere eseguita solo su piattaforme supportate dal servizio. In particolare, alcuni servizi Google Cloud supportare IAP, come App Engine.

Autenticazione gestita da app

Con questo metodo, l'app gestisce ogni aspetto dell'autenticazione utente in modo autonomo. L'app deve mantenere il proprio database di credenziali utente e gestire sessioni utente e deve fornire funzioni per gestire gli account utente e password, controllare le credenziali utente ed emettere, controllare e aggiornare le sessioni utente a ogni accesso autenticato. Il seguente diagramma illustra la gestione dell'app metodo di autenticazione.

Flusso gestito dall'applicazione

Come mostrato nel diagramma, dopo che l'utente ha eseguito l'accesso, l'app crea e mantiene le informazioni sulla sessione dell'utente. Quando l'utente invia una richiesta all'app, la richiesta deve includere informazioni sulla sessione di cui l'app è responsabile verifica.

Il vantaggio principale di questo approccio è che è indipendente, il controllo dell'app. Non è necessario che l'app disponibili su internet. Lo svantaggio principale è che l'app è ora responsabile di fornire tutte le funzionalità di gestione funzionalità e la protezione di tutti i dati sensibili delle credenziali.

Autenticazione esterna con OAuth2

Una buona alternativa alla gestione di tutto ciò che riguarda l'app è usare un servizio di identità esterno, come Google, che gestisce tutti i dati e funzionalità dell'account ed è responsabile della salvaguardia e credenziali sensibili. Quando un utente tenta di accedere all'app, viene reindirizzata al servizio di identità, che autentica l'utente e quindi reindirizza la richiesta all'app con le informazioni di autenticazione fornite. Per ulteriori informazioni, vedi Utilizzo di OAuth 2.0 per applicazioni server web.

Il seguente diagramma illustra l'autenticazione esterna con OAuth2 .

Flusso OAuth2

Il flusso nel diagramma inizia quando l'utente invia una richiesta di accesso al dell'app. Anziché rispondere direttamente, l'app reindirizza il browser dell'utente sulla piattaforma di identità di Google, che visualizza una pagina per accedere a Google. Dopo il giorno dopo aver eseguito l'accesso, il browser dell'utente viene reindirizzato all'app. Questa richiesta include informazioni che l'app può utilizzare per cercare informazioni sull'utente ora autenticato, e l'app ora risponde all'utente.

Questo metodo offre molti vantaggi per l'app. Delega tutto la funzionalità di gestione dell'account e i rischi per il servizio esterno, può migliorare la sicurezza di accesso e account senza che l'app debba farlo modifica. Tuttavia, come mostrato nel diagramma precedente, l'app deve dispongono dell'accesso a internet per utilizzare questo metodo. L'app è inoltre responsabile della gestione delle sessioni dopo l'autenticazione dell'utente.

Identity-Aware Proxy

Il terzo approccio, trattato in questo tutorial, consiste nell'utilizzare IAP per gestire l'autenticazione e la gestione delle sessioni con eventuali modifiche l'app. IAP intercetta tutte le richieste web alla tua app, blocca tutti quelli non autenticati e ne trasmette altri insieme all'utente aggiunti a ogni richiesta.

La gestione delle richieste è illustrata nel diagramma seguente.

Flusso IAP

Le richieste degli utenti vengono intercettate da IAP, che blocca per le richieste non autenticate. Le richieste autenticate vengono passate a condizione che l'utente autenticato sia nell'elenco delle app autorizzate utenti. Alle richieste trasmesse tramite IAP sono state aggiunte intestazioni identificando l'utente che ha effettuato la richiesta.

L'app non deve più gestire alcun account utente o sessione informazioni. Qualsiasi operazione che abbia bisogno di conoscere un identificatore univoco l'utente può riceverlo direttamente da ogni richiesta web in arrivo. Tuttavia, questo può Essere utilizzato solo per servizi di computing che supportano IAP, come come App Engine bilanciatori del carico. Non puoi utilizzare IAP su un computer di sviluppo locale.

Esegui la pulizia

Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

  1. Nella console Google Cloud, vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.