Authentifizierung am Server

Unter diesem Thema wird beschrieben, wie Sie sich beim Server authentifizieren, wenn Sie die Snowflake-SQL-API verwenden.

Wenn Sie eine Anforderung senden, muss diese Authentifizierungsinformationen enthalten. In den nächsten Abschnitten wird erläutert, wie Sie diese Informationen zur Anforderung hinzufügen:

Unter diesem Thema:

Verwenden von OAuth

Um OAuth zu verwenden, führen Sie die folgenden Schritte aus:

  1. Richten Sie OAuth für die Authentifizierung ein.

    Weitere Informationen zum Einrichten von OAuth und Abrufen eines OAuth-Tokens finden Sie unter Einführung in OAuth.

  2. Verwenden Sie Snowflake CLI, um zu überprüfen, ob Sie ein generiertes OAuth-Token für die Verbindung mit Snowflake verwenden können:

    • Für Linux- und MacOS-Systeme

    $ snow connection test --account <account_identifier> --user <user> --authenticator=oauth --token=<oauth_token> 
    Copy
    • Für Windows-Systeme

    $ snow connection test --account <account_identifier> --user <user> --authenticator=oauth --token=<oauth_token> 
    Copy
  3. Legen Sie in jeder API-Anforderung, die Sie senden, die folgenden Header fest:

    • Authorization: Bearer oauth_token

      Wobei oauth_token das generierte OAuth-Token ist.

    • (Optional) X-Snowflake-Authorization-Token-Type: OAUTH

      Wenn Sie die Kopfzeile X-Snowflake-Authorization-Token-Type weglassen, bestimmt Snowflake den Token-Typ, indem es das Token untersucht.

      Auch wenn diese Kopfzeile optional ist, können Sie sie angeben. Sie können die Kopfzeile auf einen der folgenden Werte setzen:

Verwenden der Schlüsselpaar-Authentifizierung

Um die Schlüsselpaar-Authentifizierung zu verwenden, führen Sie die folgenden Schritte aus:

  1. Richten Sie die Schlüsselpaar-Authentifizierung ein.

    Als Teil dieses Prozesses müssen Sie Folgendes tun:

    1. Generieren Sie ein öffentlich-privates Schlüsselpaar. Der generierte private Schlüssel muss sich in einer Datei befinden (z. B. mit dem Namen rsa_key.p8).

    2. Weisen Sie den öffentlichen Schlüssel Ihrem Snowflake-Benutzer zu. Nachdem Sie dem Benutzer den Schlüssel zugewiesen haben, führen Sie den Befehl DESCRIBE USER aus. In der Ausgabe muss die Eigenschaft RSA_PUBLIC_KEY_FP auf den Fingerabdruck des dem Benutzer zugewiesenen öffentlichen Schlüssels gesetzt sein.

    Eine Anleitung zum Generieren des Schlüsselpaars und zum Zuweisen eines Schlüssels an einen Benutzer finden Sie unter Schlüsselpaar-Authentifizierung und Schlüsselpaar-Rotation. Sprachspezifische Beispiele für das Erstellen eines Fingerabdrucks und das Generieren eines JWT-Tokens finden Sie unter:

  2. Verwenden Sie Snowflake CLI, um zu überprüfen, ob Sie den generierten privaten Schlüssel verwenden können, um eine Verbindung zu Snowflake herzustellen:

    $ snow connection generate-jwt --account <account_identifier> --user <user> --private-key-path <path>/rsa_key.p8 
    Copy

    Der Befehl fordert Sie auf, eine Passphrase für den privaten Schlüssel einzugeben, um die Verbindung herzustellen. Sie können die Aufforderung vermeiden, indem Sie die Passphrase in der Umgebungsvariablen PRIVATE_KEY_PASSPHRASE angeben.

  3. In Ihrem Anwendungscode:

    1. Generieren Sie den Fingerabdruck (einen SHA-256-Hash) des öffentlichen Schlüssels für den Benutzer. Stellen Sie dem Fingerabdruck das Präfix SHA256: voran. Beispiel:

      SHA256:hash

      Sie können auch den SQL-Befehl DESCRIBE USER ausführen, um den Wert aus der Eigenschaft RSA_PUBLIC_KEY_FP abzurufen.

    2. Generieren Sie ein JSON Web Token (JWT) mit den folgenden Feldern in der Nutzlast (Payload):

      Feld

      Beschreibung

      Beispiel

      iss

      Aussteller des JWT. Setzen Sie dies auf den folgenden Wert:

      account_identifier.user.SHA256:public_key_fingerprint

      Wobei:

      • account_identifier ist Ihr Snowflake-Kontobezeichner.

        Wenn Sie den Konto-Locator verwenden, schließen Sie alle Regionsinformationen aus dem Konto-Locator aus.

      • user ist Ihr Snowflake-Benutzername.

      • SHA256:public_key_fingerprint ist der Fingerabdruck, den Sie im vorherigen Schritt generiert haben.

      Bemerkung

      Für die Werte account_identifier und user dürfen nur Großbuchstaben verwendet werden. Wenn Ihre Konto-ID Punkte (.) enthält, müssen Sie diese durch Bindestriche (-) ersetzen, da Punkte in einem Kontobezeichner die JWT ungültig machen.

      MYORGANIZATION-MYACCOUNT.MYUSER.SHA256:public_key_fingerprint

      sub

      Subjekt des JWT. Setzen Sie dies auf den folgenden Wert:

      account_identifier.user

      MYORGANIZATION-MYACCOUNT.MYUSER

      iat

      Ausstellungszeit des JWT in UTC. Setzen Sie den Wert auf den aktuellen Zeitwert, entweder in Sekunden oder Millisekunden.

      1615370644 (Sekunden) . 1615370644000 (Millisekunden)

      exp

      Ablaufzeit des JWT in UTC. Sie können den Wert entweder in Sekunden oder Millisekunden angeben.

      Bemerkung

      Hinweis: Das JWT ist maximal eine Stunde nach Ausstellung des Tokens gültig, auch wenn Sie eine längere Ablaufzeit angeben.

      1615374184 (Sekunden) . 1615374184000 (Millisekunden)

    3. Legen Sie in jeder API-Anforderung, die Sie senden, die folgenden Header fest:

      • Authorization: Bearer JWT

        wobei JWT das Token ist, das Sie generiert haben.

      • (Optional) X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT

        Wenn Sie die Kopfzeile X-Snowflake-Authorization-Token-Type weglassen, bestimmt Snowflake den Token-Typ, indem es das Token untersucht.

        Auch wenn diese Kopfzeile optional ist, können Sie sie angeben. Sie können die Kopfzeile auf einen der folgenden Werte setzen:

Python-Beispiel

In den folgenden Abschnitten wird beschrieben, wie Sie mit Python einen JWT und einen Fingerabdruck generieren.

Ein Beispiel für das Generieren eines JWT in Python finden Sie unter sql-api-generate-jwt.py. In diesem sql-api-generate-jwt.py-Beispiel wird das PyJWT-Modul verwendet, das Sie installieren können, indem Sie Folgendes ausführen:

pip install pyjwt 
Copy

Generieren eines JWT in Python

Die folgenden Codeauszüge zeigen, wie ein JWT generiert wird. Ein vollständiges Beispiel finden Sie unter sql-api-generate-jwt.py.

Bemerkung

Dieses Beispiel soll nur als Referenz dienen. Verwenden Sie diesen Code nicht in Produktionsanwendungen oder -umgebungen.

from datetime import timedelta, timezone, datetime # This example relies on the PyJWT module (https://pypi.org/project/PyJWT/). import jwt # Construct the fully qualified name of the user in uppercase. # - Replace <account_identifier> with your account identifier. # (See https://docs.snowflake.com/en/user-guide/admin-account-identifier.html .) # - Replace <user_name> with your Snowflake user name. account = "<account_identifier>" # Get the account identifier without the region, cloud provider, or subdomain. if not '.global' in account: idx = account.find('.') if idx > 0: account = account[0:idx] else: # Handle the replication case. idx = account.find('-') if idx > 0: account = account[0:idx] # Use uppercase for the account identifier and user name. account = account.upper() user = "<user_name>".upper() qualified_username = account + "." + user # Get the current time in order to specify the time when the JWT was issued and the expiration time of the JWT. now = datetime.now(timezone.utc) # Specify the length of time during which the JWT will be valid. You can specify at most 1 hour. lifetime = timedelta(minutes=59) # Create the payload for the token. payload = { # Set the issuer to the fully qualified username concatenated with the public key fingerprint (calculated in the previous step). "iss": qualified_username + '.' + public_key_fp, # Set the subject to the fully qualified username. "sub": qualified_username, # Set the issue time to now. "iat": now, # Set the expiration time, based on the lifetime specified for this object. "exp": now + lifetime } # Generate the JWT. private_key is the private key that you read from the private key file in the previous step when you generated the public key fingerprint. encoding_algorithm="RS256" token = jwt.encode(payload, key=private_key, algorithms=encoding_algorithm) # If you are using a version of PyJWT prior to 2.0, jwt.encode returns a byte string, rather than a string. # If the token is a byte string, convert it to a string. if isinstance(token, bytes): token = token.decode('utf-8') print(token) decoded_token = jwt.decode(token, key=private_key.public_key(), algorithms=[encoding_algorithm]) print("Generated a JWT with the following payload:\n{}".format(decoded_token)) 
Copy

Generieren eines Fingerabdrucks in Python

Die folgenden Codeauszüge zeigen, wie der Fingerabdruck generiert wird. Ein vollständiges Beispiel finden Sie unter sql-api-generate-jwt.py.

from cryptography.hazmat.primitives.serialization import load_pem_private_key from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import PublicFormat from cryptography.hazmat.backends import default_backend .. import base64 from getpass import getpass import hashlib .. # If you generated an encrypted private key, implement this method to return # the passphrase for decrypting your private key. As an example, this function # prompts the user for the passphrase. def get_private_key_passphrase(): return getpass('Passphrase for private key: ') # Private key that you will load from the private key file. private_key = None # Open the private key file. # Replace <private_key_file_path> with the path to your private key file (e.g. /x/y/z/rsa_key.p8). with open('<private_key_file_path>', 'rb') as pem_in: pemlines = pem_in.read() try: # Try to access the private key without a passphrase. private_key = load_pem_private_key(pemlines, None, default_backend()) except TypeError: # If that fails, provide the passphrase returned from get_private_key_passphrase(). private_key = load_pem_private_key(pemlines, get_private_key_passphrase().encode(), default_backend()) # Get the raw bytes of the public key. public_key_raw = private_key.public_key().public_bytes(Encoding.DER, PublicFormat.SubjectPublicKeyInfo) # Get the sha256 hash of the raw bytes. sha256hash = hashlib.sha256() sha256hash.update(public_key_raw) # Base64-encode the value and prepend the prefix 'SHA256:'. public_key_fp = 'SHA256:' + base64.b64encode(sha256hash.digest()).decode('utf-8') 
Copy

Snowflake CLI-Beispiel

Sie können mit dem Befehl Snowflake CLI snow connection generate-jwt einen JWT für die Schlüsselpaar-Authentifizierung generieren. Weitere Informationen dazu finden Sie unter snow connection generate-jwt.

Dieses Beispiel generiert ein Token für das TEST-Konto und den JDOE-Benutzer, wobei der private Schlüssel von rsa_key.p8 verwendet wird:

snow connection generate-jwt --user JDOE --account TEST --private-key-file=rsa_key.p8 
Copy

Der Befehl fordert Sie auf, eine Passphrase für den privaten Schlüssel einzugeben, um die Verbindung herzustellen. Sie können die Aufforderung vermeiden, indem Sie die Passphrase in der Umgebungsvariablen PRIVATE_KEY_PASSPHRASE angeben.

Java-Beispiel

Ein Beispiel für das Generieren eines JWT in Java finden Sie unter SimpleStatementsApi.java.

Bemerkung

Dieses Beispiel soll nur als Referenz dienen. Verwenden Sie diesen Code nicht in Produktionsanwendungen oder -umgebungen.

In diesem Beispiel werden die folgenden Bibliotheken von Drittanbietern verwendet:

  • Swagger Codegen: eine Open-Source-Bibliothek für die Entwicklung von REST-APIs und Anwendungen.

  • Auth0: Bietet Java-APIs zum Authentifizieren und Generieren von JWT-Tokens.

Node.js-Beispiel

Ein Beispiel für das Generieren eines JWT in Node.js finden Sie unter sql-api-generate-jwt.js.

Bemerkung

Dieses Beispiel soll nur als Referenz dienen. Verwenden Sie diesen Code nicht in Produktionsanwendungen oder -umgebungen.