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 SnowSQL, 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

    $ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token=<oauth_token>
    
    Copy
    • Für Windows-Systeme

    $ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token="<oauth_token>"
    
    Copy
  3. Legen Sie in Ihrem Anwendungscode in jeder API-Anforderung, die Sie senden, die folgenden Header fest:

    • Authorization: Bearer oauth_token

      Wobei oauth_token das generierte OAuth-Token ist.

    • X-Snowflake-Authorization-Token-Type: OAUTH

      Beachten Sie, dass Sie den Header X-Snowflake-Authorization-Token-Type auch weglassen können. Wenn dieser Header nicht vorhanden ist, nimmt Snowflake an, dass das Token im Authorization-Header ein OAuth-Token ist.

    • Snowflake-Account: account_locator

      Wenn Sie OAuth mit einer URL verwenden, die den Kontonamen der Organisation angibt, müssen Sie diese Kopfzeile einfügen. Siehe Übermitteln von Abfragen an URLs mit einem Kontonamen einer Organisation (nur OAuth).

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 SnowSQL, um zu überprüfen, ob Sie den generierten privaten Schlüssel verwenden können, um eine Verbindung zu Snowflake herzustellen:

    $ snowsql -a <account_identifier> -u <user> --private-key-path <path>/rsa_key.p8
    
    Copy

    Wenn Sie einen verschlüsselten privaten Schlüssel generiert haben, fordert SnowSQL Sie zur Eingabe der Passphrase auf, die Sie beim Generieren des Schlüssels erstellt haben.

  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

    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.

      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.

      • X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT

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. Im folgenden 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, algorithm=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')
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

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.