Authentification auprès du serveur¶
Cette rubrique décrit comment s’authentifier auprès du serveur lors de l’utilisation de l’API SQL de Snowflake.
Lorsque vous envoyez une requête, celle-ci doit inclure des informations d’authentification. Les sections suivantes expliquent comment ajouter ces informations à la requête :
Dans ce chapitre :
Utilisation de OAuth¶
Pour utiliser OAuth, suivez les étapes suivantes :
Configurez OAuth pour l’authentification.
Voir Introduction à OAuth pour plus de détails sur la façon de configurer OAuth et d’obtenir un jeton OAuth.
Utilisez SnowSQL pour vérifier que vous pouvez utiliser un jeton OAuth généré pour vous connecter à Snowflake :
Pour les systèmes Linux et MacOS
$ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token=<oauth_token>
Pour les systèmes Windows
$ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token="<oauth_token>"
Dans chaque requête d’API que vous envoyez, définissez les en-têtes suivants :
Authorization: Bearer oauth_token
où
oauth_token
est le jeton OAuth généré.X-Snowflake-Authorization-Token-Type: OAUTH
Notez que vous pouvez également choisir d’omettre l’en-tête
X-Snowflake-Authorization-Token-Type
. Si cet en-tête n’est pas présent, Snowflake suppose que le jeton dans l’en-têteAuthorization
est un jeton OAuth.
Utilisation de l’authentification par paire de clés¶
Pour utiliser l’authentification par paire de clés, suivez ces étapes :
Configurez l’authentification par paire de clés.
Dans le cadre de ce processus, vous devez :
Générer une paire de clés publique-privée. La clé privée générée doit se trouver dans un fichier (par exemple, nommé
rsa_key.p8
).Attribuez la clé publique à votre utilisateur Snowflake. Après avoir attribué la clé à l’utilisateur, exécutez la commande DESCRIBE USER. Dans la sortie, la propriété
RSA_PUBLIC_KEY_FP
doit être définie comme l’empreinte de la clé publique attribuée à l’utilisateur.
Pour des instructions sur la façon de générer la paire de clés et d’attribuer une clé à un utilisateur, voir Authentification par paire de clés et rotation de paires de clés. Pour des exemples de création d’une empreinte et de la génération d’un jeton JWT spécifiques à un langage, voir ce qui suit :
Utilisez SnowSQL pour vérifier que vous pouvez utiliser la clé privée générée pour vous connecter à Snowflake :
$ snowsql -a <account_identifier> -u <user> --private-key-path <path>/rsa_key.p8
Si vous avez généré une clé privée cryptée, SnowSQL vous invite à saisir la phrase secrète que vous avez créée lors de la génération de la clé.
Dans le code de votre application :
Générez l’empreinte digitale (un hachage SHA-256) de la clé publique de l’utilisateur. Préfixez l’empreinte digitale avec
SHA256:
. Par exemple :SHA256:hash
Vous pouvez également exécuter la commande SQL DESCRIBE USER pour obtenir la valeur de la propriété RSA_PUBLIC_KEY_FP.
Générez un jeton Web JSON (JWT) avec les champs suivants dans la charge utile :
Champ
Description
Exemple
iss
Émetteur du JWT. Réglez-le sur la valeur suivante :
account_identifier.user.SHA256:public_key_fingerprint
où :
account_identifier
est votre identificateur de compte Snowflake.Si vous utilisez le localisateur de compte, excluez toute information sur la région du localisateur de compte.
user
est votre nom d’utilisateur Snowflake.SHA256:public_key_fingerprint
est l’empreinte de la clé que vous avez générée à l’étape précédente.
Note
Les valeurs
account_identifier
etuser
doivent utiliser tous les caractères majuscules. Si votre ID de compte contient des points (.
), vous devez les remplacer par des traits d’union (-
), car les points dans un identificateur de compte rendent le JWT non valide.MYORGANIZATION-MYACCOUNT.MYUSER.SHA256:public_key_fingerprint
sub
Objet pour le JWT. Réglez-le sur la valeur suivante :
account_identifier.user
MYORGANIZATION-MYACCOUNT.MYUSER
iat
Heure d’émission pour les JWT au format UTC. Définissez la valeur de l’heure actuelle en secondes ou en millisecondes.
1615370644
(secondes) .1615370644000
(millisecondes)exp
Heure d’expiration pour les JWT au format UTC. Vous pouvez spécifier la valeur en secondes ou en millisecondes.
Note
Le JWT est valide au maximum une heure après l’émission du jeton, même si vous spécifiez un délai d’expiration plus long.
1615374184
(secondes) .1615374184000
(millisecondes)Dans chaque requête API que vous envoyez, définissez les en-têtes suivants :
Authorization: Bearer JWT
où
JWT
est le jeton que vous avez généré.X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT
Exemple Python¶
Les sections suivantes décrivent comment générer un JWT et une empreinte à l’aide de Python.
Pour un exemple de génération d’un JWT en Python, voir sql-api-generate-jwt.py
. L’exemple sql-api-generate-jwt.py
utilise le module PyJWT, que vous pouvez installer en exécutant :
pip install pyjwt
Génération d’un jeton JWT en Python¶
Les sections de code suivantes démontrent comment générer un JWT. Pour un exemple complet, voir sql-api-generate-jwt.py
.
Note
Cet exemple est destiné à servir de référence uniquement. N’utilisez pas ce code dans des applications ou des environnements de production.
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))
Génération d’une empreinte en Python¶
Les sections de code suivantes montrent comment générer l’empreinte digitale. Pour un exemple complet, voir 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')
Exemple Java¶
Pour un exemple de génération d’un jeton JWT en Java, voir SimpleStatementsApi.java
.
Note
Cet exemple est destiné à servir de référence uniquement. N’utilisez pas ce code dans des applications ou des environnements de production.
Cet exemple utilise les bibliothèques tierces suivantes :
Swagger Codegen : une bibliothèque open source utile pour le développement d’APIs REST et d’applications.
Auth0 : fournit des APIs Java pour l’authentification et la génération de jetons JWT.
Exemple Node.js¶
Pour un exemple de génération d’un JWT en Node.js, voir sql-api-generate-jwt.js
.
Note
Cet exemple est destiné à servir de référence uniquement. N’utilisez pas ce code dans des applications ou des environnements de production.