Autenticazione API Looker tramite OAuth

Looker utilizza OAuth per consentire alle applicazioni client OAuth di eseguire l'autenticazione nell'API Looker senza esporre gli ID client e i client secret al browser su cui viene eseguita l'applicazione client OAuth.

Le applicazioni web che utilizzano OAuth devono soddisfare i seguenti requisiti:

  • L'autenticazione mediante OAuth è disponibile solo con l'API Looker 4.0.
  • Le applicazioni client OAuth devono essere registrate in Looker utilizzando l'API prima che gli utenti dell'applicazione possano eseguire l'autenticazione in Looker.
  • Le applicazioni client devono utilizzare HTTPS per tutte le richieste all'API Looker. Le applicazioni client che vogliono utilizzare le API SubtleCrypto fornite dal browser devono essere ospitate su HTTPS.

Supporto CORS API Looker

L'API Looker supporta le chiamate nel browser e in più origini utilizzando il protocollo CORS (Cross-Origin Resource Sharing). Il supporto CORS di Looker prevede i seguenti requisiti:

  • Solo le origini elencate nella lista consentita di domini incorporati possono chiamare l'API utilizzando CORS.
  • È possibile utilizzare solo i token di accesso ottenuti da OAuth o dalla chiamata all'endpoint API /login per effettuare chiamate all'API Looker utilizzando CORS.

    Non è possibile chiamare l'endpoint dell'API /login utilizzando le richieste CORS. Le applicazioni client che vogliono chiamare l'API Looker utilizzando le richieste CORS devono utilizzare la procedura di accesso OAuth descritta in Eseguire l'accesso utente utilizzando OAuth oppure recuperare un token dal server delle applicazioni o da chiamate API non CORS.

Panoramica dell'autenticazione OAuth

Di seguito è riportata una panoramica del processo di autenticazione OAuth:

  1. Registra l'applicazione client OAuth con l'API Looker.
  2. Aggiungi l'origine della tua applicazione client OAuth alla lista consentita di domini incorporati per la chiamata API per lo scambio di codice e le eventuali chiamate API CORS successive.
  3. Reindirizza l'URL del browser all'endpoint /auth del nome host dell'interfaccia utente di Looker (non al nome host dell'API Looker) quando l'applicazione client OAuth tenta di autenticare un utente. Ad esempio, https://instance_name.looker.com.
  4. Se l'utente viene autenticato e ha eseguito l'accesso a Looker, Looker restituisce immediatamente un reindirizzamento OAuth all'applicazione client OAuth. Se l'utente non ha ancora eseguito l'accesso a Looker sul dispositivo e nel browser correnti, viene visualizzata la schermata di accesso di Looker e viene chiesto all'utente di accedere al proprio account utente Looker utilizzando il proprio protocollo di autenticazione standard.
  5. Utilizzando il codice di autorizzazione restituito nel reindirizzamento OAuth, l'applicazione client OAuth deve quindi effettuare una chiamata all'endpoint /token del nome host dell'API Looker, ad esempio https://instance_name.looker.com:19999. Il nome host dell'API potrebbe essere uguale o diverso dal nome host dell'interfaccia utente di Looker. L'endpoint /token esiste solo nell'host dell'API Looker e l'endpoint /auth esiste solo nell'host dell'interfaccia utente di Looker.
  6. Se il codice di autorizzazione passato all'endpoint /token è valido, Looker restituisce un'API access_token che è abilitata per le richieste API CORS dal dominio dell'applicazione client OAuth.

Registrazione di un'applicazione client OAuth

Ogni applicazione client OAuth che tenta di eseguire l'autenticazione nell'API Looker utilizzando OAuth deve essere registrata con l'istanza di Looker prima che Looker autorizzi l'accesso. Per registrare un'applicazione client OAuth:

  1. Apri API Explorer nella tua istanza di Looker.
  2. Dal menu a discesa della versione, scegli la versione 4.0 - stabile dell'API.
  3. Nel metodo Auth, trova l'endpoint dell'API register_oauth_client_app(). Puoi anche cercare "app di autenticazione" nel campo Cerca. Puoi utilizzare register_oauth_client_app() per registrare la tua applicazione client OAuth con Looker. Fai clic sul pulsante Esegui e inserisci i parametri in Explorer API e fai nuovamente clic su Esegui per registrare l'applicazione client OAuth oppure utilizza l'endpoint API register_oauth_client_app() in modo programmatico. I parametri register_oauth_client_app() obbligatori sono:

    • client_guid: un ID univoco globale per l'applicazione
    • redirect_uri: l'URI in cui l'applicazione riceverà un reindirizzamento OAuth che include un codice di autorizzazione
    • display_name: il nome dell'applicazione che viene mostrato agli utenti dell'applicazione
    • description: una descrizione dell'applicazione che viene mostrata agli utenti in una pagina informativa e di conferma quando un utente accede per la prima volta dall'applicazione.

    I valori nei parametri client_guid e redirect_uri devono corrispondere ai valori forniti esattamente dall'applicazione client OAuth, altrimenti l'autenticazione viene rifiutata.

Eseguire l'accesso utente utilizzando OAuth

  1. Porta l'utente all'endpoint /auth sull'host dell'interfaccia utente. Ad esempio:

    async function oauth_login() {
      const code_verifier = secure_random(32)
      const code_challenge = await sha256_hash(code_verifier)
      const params = {
        response_type: 'code',
        client_id: '123456',
        redirect_uri: 'https://mywebapp.com:3000/authenticated',
        scope: 'cors_api',
        state: '1235813',
        code_challenge_method: 'S256',
        code_challenge: code_challenge,
      }
      const url = `${base_url}?${new URLSearchParams(params).toString()}` // Replace base_url with your full Looker instance's UI host URL, plus the `/auth` endpoint.
      log(url)
    
      // Stash the code verifier we created in sessionStorage, which
      // will survive page loads caused by login redirects
      // The code verifier value is needed after the login redirect
      // to redeem the auth_code received for an access_token
      //
      sessionStorage.setItem('code_verifier', code_verifier)
    
      document.location = url
    }
    
    function array_to_hex(array) {
      return Array.from(array).map(b => b.toString(16).padStart(2,'0')).join('')
    }
    
    function secure_random(byte_count) {
      const array = new Uint8Array(byte_count);
      crypto.getRandomValues(array);
      return array_to_hex(array)
    }
    
    async function sha256_hash(message) {
      const msgUint8 = new TextEncoder().encode(message)
      const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)
      return base64.urlEncode(hashBuffer))  // Refers to the implementation of base64.encode stored at https://gist.github.com/jhurliman/1250118
    }
    

    Il codice campione sopra riportato si basa sulle API SubtleCrypto fornite dal browser, ma il browser consentirà di utilizzare queste funzioni solo da pagine web sicure (HTTPS).

    Looker tenterà di autenticare l'utente utilizzando il sistema di autenticazione per il quale è configurata l'istanza di Looker.

    • Se l'utente ha già eseguito l'accesso a Looker nel browser corrente (ovvero è presente uno stato dei cookie di accesso in tempo reale), all'utente non verrà chiesto di inserire le proprie credenziali di accesso.
    • Se è la prima volta che l'utente accede utilizzando questa applicazione client OAuth, Looker mostrerà una pagina di conferma e conferma all'utente, che dovrà confermarlo e accettarlo. Verrà visualizzato il testo del parametro description utilizzato al momento della registrazione dell'applicazione. La descrizione dovrebbe indicare cosa deve fare l'applicazione con l'account Looker dell'utente. Quando l'utente fa clic su accetta, la pagina viene reindirizzata all'applicazione redirect_uri.
    • Se l'utente ha già effettuato l'accesso a Looker nel browser corrente e ha già confermato la pagina di divulgazione, l'accesso OAuth è istantaneo senza interruzioni visive.
  2. L'API Looker restituirà un reindirizzamento OAuth all'applicazione client OAuth. Salva il codice di autorizzazione elencato nel parametro URI. Di seguito è riportato un URI di reindirizzamento OAuth di esempio:

    https://mywebapp.com:3000/authenticated?&code=asdfasdfassdf&state=...
    

    Il codice di autorizzazione è riportato dopo &code= nell'URI. Nell'esempio precedente, il codice di autorizzazione è asdfasdfassdf.

  3. Effettua una richiesta web all'endpoint /token nell'API Looker, trasmettendo il codice di autorizzazione e le informazioni dell'applicazione. Ad esempio:

    async function redeem_auth_code(response_str) {
      const params = new URLSearchParams(response_str)
      const auth_code = params.get('code')
    
      if (!auth_code) {
        log('ERROR: No authorization code in response')
        return
      }
      log(`auth code received: ${auth_code}`)
      log(`state: ${params.get('state')}`)
    
      const code_verifier = sessionStorage.getItem('code_verifier')
      if (!code_verifier) {
        log('ERROR: Missing code_verifier in session storage')
        return
      }
      sessionStorage.removeItem('code_verifier')
      const response = await
      fetch('https://mycompany.looker.com:19999/api/token', {  // This is the URL of your Looker instance's API web service
        method: 'POST',
        mode: 'cors',    // This line is required so that the browser will attempt a CORS request.
        body: stringify({
          grant_type: 'authorization_code',
          client_id: '123456',
          redirect_uri: 'https://mywebapp.com:3000/authenticated',
          code: auth_code,
          code_verifier: code_verifier,
        }),
        headers: {
          'x-looker-appid': 'Web App Auth & CORS API Demo', // This header is optional.
          'Content-Type': 'application/json;charset=UTF-8'  // This header is required.
        },
      }).catch((error) => {
        log(`Error: ${error.message}`)
      })
    
      const info = await response.json()
      log(`/api/token response: ${stringify(info)}`)
    
      // Store the access_token and other info,
      // which in this example is done in sessionStorage
    
      const expires_at = new Date(Date.now() + (info.expires_in * 1000))
      info.expires_at = expires_at
      log(`Access token expires at ${expires_at.toLocaleTimeString()} local time.`)
      sessionStorage.setItem('access_info', stringify(info))
      access_info = info
    }
    

    Una risposta riuscita fornirà all'applicazione client OAuth un'API access_token. La risposta conterrà inoltre un refresh_token, che puoi utilizzare in un secondo momento per ottenere un nuovo access_token senza interazione dell'utente. refresh_token ha una durata di un mese. Conserva refresh_token in modo sicuro.

    Tutti i token in questo sistema possono essere revocati dall'amministratore di Looker in qualsiasi momento.