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:
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.
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>
Für Windows-Systeme
$ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token="<oauth_token>"
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.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 imAuthorization
-Header ein OAuth-Token ist.
Verwenden der Schlüsselpaar-Authentifizierung¶
Um die Schlüsselpaar-Authentifizierung zu verwenden, führen Sie die folgenden Schritte aus:
Richten Sie die Schlüsselpaar-Authentifizierung ein.
Als Teil dieses Prozesses müssen Sie Folgendes tun:
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
).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:
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
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.
In Ihrem Anwendungscode:
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.
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
unduser
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)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
. 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
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))
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')
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.