Looker API-Authentifizierung mit OAuth

Looker verwendet OAuth, damit sich OAuth-Clientanwendungen bei der Looker API authentifizieren können, ohne Client-IDs und Clientschlüssel für den Browser freizugeben, in dem die OAuth-Clientanwendung ausgeführt wird.

Webanwendungen, die OAuth verwenden, müssen die folgenden Anforderungen erfüllen:

  • Die Authentifizierung mit OAuth ist nur mit der Looker API 4.0 verfügbar.
  • OAuth-Clientanwendungen müssen zuerst über die API bei Looker registriert werden, bevor sich Nutzer der Anwendung bei Looker authentifizieren können.
  • Clientanwendungen müssen für alle Anfragen an die Looker API HTTPS verwenden. Clientanwendungen, die die vom Browser bereitgestellten SubtleCrypto APIs verwenden möchten, müssen HTTPS-gehostet sein.

CORS-Unterstützung für Looker API

Die Looker API kann im Browser und über verschiedene Ursprünge mit dem Cross-Origin Resource Sharing-Protokoll (CORS) aufgerufen werden. Für die Looker-CORS-Unterstützung gelten die folgenden Anforderungen:

  • Nur Ursprünge in der Zulassungsliste für eingebettete Domains können die API mithilfe von CORS aufrufen.
  • Nur Zugriffstokens, die von OAuth oder durch Aufrufen des /login API-Endpunkts abgerufen wurden, können zum Aufrufen der Looker API mithilfe von CORS verwendet werden.

    Der API-Endpunkt /login kann nicht mit CORS-Anfragen aufgerufen werden. Clientanwendungen, die die Looker API mithilfe von CORS-Anfragen aufrufen möchten, müssen entweder den OAuth-Anmeldeprozess verwenden, der unter Nutzeranmeldung mit OAuth ausführen beschrieben ist, oder ein Token von Ihrem Anwendungsserver oder von Nicht-CORS-API-Aufrufen abrufen.

OAuth-Authentifizierung

Der OAuth-Authentifizierungsprozess sieht so aus:

  1. Registrieren Sie die OAuth-Clientanwendung mit der Looker API.
  2. Fügen Sie den Ursprung Ihrer OAuth-Clientanwendung der Zulassungsliste der eingebetteten Domains für den Code Exchange API-Aufruf und alle nachfolgenden CORS API-Aufrufe hinzu.
  3. Weiterleiten der Browser-URL an den Endpunkt /auth auf dem Hostnamen der Looker-UI (nicht dem Hostnamen der Looker API), wenn die OAuth-Clientanwendung versucht, einen Nutzer zu authentifizieren. Beispiel: https://instance_name.looker.com.
  4. Wenn der Nutzer erfolgreich authentifiziert und bei Looker angemeldet ist, gibt Looker sofort eine OAuth-Weiterleitung an die OAuth-Clientanwendung zurück. Wenn der Nutzer auf dem aktuellen Gerät und im aktuellen Browser nicht bereits in Looker angemeldet ist, wird der Looker-Anmeldebildschirm angezeigt und der Nutzer wird aufgefordert, sich mit seinem regulären Authentifizierungsprotokoll in seinem Looker-Nutzerkonto anzumelden.
  5. Mit dem in der OAuth-Weiterleitung zurückgegebenen Autorisierungscode sollte Ihre OAuth-Clientanwendung als Nächstes den Endpunkt /token für den Looker API-Hostnamen aufrufen, z. B. https://instance_name.looker.com:19999. Der Hostname der API kann mit dem Hostnamen der Looker-Benutzeroberfläche identisch oder davon abweichen. Der Endpunkt /token ist nur auf dem Looker API-Host und der Endpunkt /auth nur auf dem Looker-UI-Host vorhanden.
  6. Wenn der an den Endpunkt /token übergebene Autorisierungscode gültig ist, gibt Looker eine API access_token zurück, die für CORS API-Anfragen von der Domain der OAuth-Clientanwendung aktiviert ist.

OAuth-Clientanwendung registrieren

Jede OAuth-Clientanwendung, die versucht, sich mit OAuth bei der Looker API zu authentifizieren, muss zuerst bei der Looker-Instanz registriert werden, bevor Looker den Zugriff autorisiert. So registrieren Sie eine OAuth-Clientanwendung:

  1. Öffnen Sie den API Explorer auf Ihrer Looker-Instanz.
  2. Wählen Sie im Drop-down-Menü „Version“ die Version 4.0 – stabile Version der API aus.
  3. Suchen Sie unter der Methode Auth nach dem API-Endpunkt register_oauth_client_app(). Sie können auch im Feld Suchen nach „oauth app“ suchen. Sie können register_oauth_client_app() verwenden, um Ihre OAuth-Clientanwendung bei Looker zu registrieren. Klicken Sie auf die Schaltfläche Ausführen und geben Sie die Parameter in API Explorer ein. Klicken Sie dann noch einmal auf Ausführen, um die OAuth-Clientanwendung zu registrieren, oder verwenden Sie den API-Endpunkt register_oauth_client_app() programmatisch. Die erforderlichen register_oauth_client_app()-Parameter sind:

    • client_guid: Eine global eindeutige ID für die Anwendung
    • redirect_uri: Der URI, an den die Anwendung eine OAuth-Weiterleitung empfängt, die einen Autorisierungscode enthält
    • display_name: Der Name der Anwendung, der Nutzern der Anwendung angezeigt wird.
    • description: Eine Beschreibung der Anwendung, die Nutzern auf einer Offenlegungs- und Bestätigungsseite angezeigt wird, wenn sich ein Nutzer zum ersten Mal über die Anwendung anmeldet

    Die Werte in den Parametern client_guid und redirect_uri müssen mit den Werten übereinstimmen, die die OAuth-Clientanwendung exakt bereitstellt. Andernfalls wird die Authentifizierung verweigert.

Nutzeranmeldung mit OAuth

  1. Rufen Sie auf dem UI-Host den Nutzer zum Endpunkt /auth auf. Beispiel:

    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
    }
    

    Der Beispielcode basiert auf SubtleCrypto APIs, die vom Browser bereitgestellt werden. Im Browser sind diese Funktionen jedoch nur auf sicheren (HTTPS-)Webseiten zulässig.

    Looker versucht, den Nutzer mithilfe des Authentifizierungssystems zu authentifizieren, für das die Looker-Instanz konfiguriert ist.

    • Wenn der Nutzer bereits im aktuellen Browser bei Looker angemeldet ist (das bedeutet, dass ein Cookie-Status für die Live-Anmeldung vorliegt), wird der Nutzer nicht aufgefordert, seine Anmeldedaten einzugeben.
    • Wenn sich der Nutzer das erste Mal mit dieser OAuth-Clientanwendung angemeldet hat, zeigt Looker eine Offenlegungs- und Bestätigungsseite an, die der Nutzer bestätigen und akzeptieren kann. Der Text aus dem Parameter description, der bei der Registrierung der Anwendung verwendet wurde, wird angezeigt. Die Beschreibung sollte angeben, was die Anwendung mit dem Looker-Konto des Nutzers tun soll. Wenn der Nutzer auf Akzeptieren klickt, wird er auf die Seite redirect_uri weitergeleitet.
    • Wenn der Nutzer bereits im aktuellen Browser bei Looker angemeldet ist und die Seite zur Offenlegung bereits bestätigt hat, erfolgt die OAuth-Anmeldung sofort und ohne visuelle Unterbrechung.
  2. Die Looker API gibt eine OAuth-Weiterleitung an die OAuth-Clientanwendung zurück. Speichern Sie den Autorisierungscode, der im URI-Parameter aufgeführt ist. Hier ein Beispiel für einen OAuth-Weiterleitungs-URI:

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

    Der Autorisierungscode wird im URI nach &code= angezeigt. Im Beispiel oben lautet der Autorisierungscode asdfasdfassdf.

  3. Stellen Sie in der Looker API eine Webanfrage an den Endpunkt /token und übergeben Sie den Autorisierungscode sowie Ihre Anwendungsinformationen. Beispiel:

    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
    }
    

    Eine erfolgreiche Antwort liefert der OAuth-Clientanwendung die API access_token. Die Antwort enthält auch eine refresh_token, die Sie später verwenden können, um eine neue access_token ohne Nutzerinteraktion zu erhalten. refresh_token hat eine Lebensdauer von einem Monat. Bewahren Sie die refresh_token sicher auf.

    Alle Tokens in diesem System können vom Looker-Administrator jederzeit widerrufen werden.