Configurer Snowflake OAuth pour les clients personnalisés¶
Ce chapitre décrit comment configurer la prise en charge de OAuth pour les clients personnalisés.
Dans ce chapitre :
Workflow¶
Les étapes de haut niveau suivantes sont requises pour configurer OAuth pour les clients personnalisés :
Enregistrez votre client avec Snowflake. Pour enregistrer votre client, créez une intégration. Une intégration est un objet Snowflake qui fournit une interface entre Snowflake et des services tiers, tels qu’un client prenant en charge OAuth.
Le processus d’inscription définit un ID de client et des secrets de client.
Configurez les appels aux points de terminaison OAuth de Snowflake pour demander des codes d’autorisation au serveur d’autorisation de Snowflake, ainsi que pour demander et actualiser des jetons d’accès.
Les paramètres facultatifs « scope » de la demande d’autorisation initiale limitent le rôle autorisé par le jeton d’accès et peuvent également être utilisés pour configurer le comportement du jeton d’actualisation.
Note
Le changement de rôle en cours de session vers des rôles secondaires n’est pas pris en charge par Snowflake OAuth.
Si ce comportement est nécessaire avec votre flux de travail OAuth, utilisez plutôt OAuth externe.
Pour plus d’informations, voir Utilisation de rôles secondaires avec External OAuth.
Créer une intégration OAuth Snowflake¶
Créez une intégration Snowflake OAuth en utilisant la commande CREATESECURITY INTEGRATION. Veillez à spécifier OAUTH_CLIENT = CUSTOM
lors de la création de l’intégration.
Note
Seuls les administrateurs de compte (utilisateurs dotés du rôle ACCOUNTADMIN) ou un rôle disposant du privilège global CREATE INTEGRATION peuvent exécuter cette commande SQL.
Blocage de rôles spécifiques pour les empêcher d’utiliser l’intégration¶
Le paramètre BLOCKED_ROLES_LIST facultatif vous permet de répertorier les rôles Snowflake qu’un utilisateur ne peut pas consentir explicitement d’utiliser avec l’intégration.
Par défaut, les rôles ACCOUNTADMIN, SECURITYADMIN, et ORGADMIN sont inclus dans cette liste et ne peuvent pas être supprimés. Si votre entreprise a besoin d’autoriser des utilisateurs à utiliser OAuth de Snowflake avec ces rôles et que votre équipe de sécurité le permet, contactez le support de Snowflake pour demander que ces rôles soient autorisés pour votre compte.
Utilisation de la redirection des clients avec des clients personnalisés OAuth Snowflake¶
Snowflake prend en charge l’utilisation de la redirection des clients avec des clients personnalisés OAuth Snowflake, y compris l’utilisation de la redirection des clients et OAuth avec les clients Snowflake pris en charge.
Pour plus d’informations, voir Rediriger les connexions du client.
Gestion des politiques réseau¶
Snowflake prend en charge les politiques réseau pour OAuth. Pour plus d’informations, voir Politiques réseau.
Exemple d’intégration¶
L’exemple suivant crée une intégration OAuth qui utilise l’authentification par paire de clés. L’intégration permet d’actualiser les jetons, qui expirent après 1 jour (86 400 secondes). L’intégration empêche les utilisateurs de démarrer une session avec SYSADMIN comme rôle actif :
CREATE SECURITY INTEGRATION oauth_kp_int
TYPE = OAUTH
ENABLED = TRUE
OAUTH_CLIENT = CUSTOM
OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
OAUTH_REDIRECT_URI = 'https://localhost.com'
OAUTH_ISSUE_REFRESH_TOKENS = TRUE
OAUTH_REFRESH_TOKEN_VALIDITY = 86400
BLOCKED_ROLES_LIST = ('SYSADMIN')
OAUTH_CLIENT_RSA_PUBLIC_KEY ='
MIIBI
...
';
Appel des points de terminaison OAuth¶
Les points de terminaison OAuth sont les URLs que les clients appellent pour demander des codes d’autorisation et pour demander et actualiser des jetons d’accès. Ces points de terminaison font référence à des règles spécifiques OAuth 2.0 qui s’exécutent lorsque le point de terminaison est appelé.
Snowflake fournit les points de terminaison OAuth suivants :
- Autorisation:
<snowflake_account_url>/oauth/authorize
- Demandes de jetons:
<snowflake_account_url>/oauth/token-request
Où <snowflake_account_url>
est une URL de compte Snowflake valide. Par exemple, vous pouvez utiliser les points de terminaison https://myorg-account_xyz.snowflakecomputing.com/oauth/authorize
et https://myorg-account_xyz.snowflakecomputing.com/oauth/token-request
. Pour une liste des formats pris en charge pour l’URL de compte Snowflake , voir Connexion avec une URL.
Afin de voir la liste des points de terminaison OAuth valides pour une intégration de sécurité, exécutez DESCRIBE INTEGRATION, puis visualisez les valeurs des propriétés OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS
et OAUTH_ALLOWED_TOKEN_ENDPOINTS
.
Point de terminaison de jeton¶
Ce point de terminaison renvoie des jetons d’accès ou des jetons d’actualisation en fonction des paramètres de la demande. Le point de terminaison du jeton est le suivant :
<snowflake_account_url>/oauth/token-request
Où :
snowflake_account_url
Spécifie une URL de compte Snowflake valide. Par exemple,
https://myorg-account_xyz.snowflakecomputing.com/oauth/token-request
.
Méthode HTTP¶
POST
Assurez-vous que l’en-tête de type de contenu dans la requête POST est défini comme suit :
Content-type: application/x-www-form-urlencoded
En-tête de requête¶
L’ID de client et le secret du client doivent être inclus dans l’en-tête d’autorisation. Actuellement, Snowflake ne prend en charge que le schéma d’authentification de base, ce qui signifie que la valeur attendue est sous la forme suivante :
Basic Base64(client_id:client_secret)
Où :
Valeur de l’en-tête |
Type de données |
Obligatoire |
Description |
---|---|---|---|
|
Chaîne |
Oui |
ID de client de l’intégration. |
|
Chaîne |
Oui |
Secret du client pour l’intégration. |
L’ID et le secret du client peuvent être récupérés à l’aide de la fonction SYSTEM$SHOW_OAUTH_CLIENT_SECRETS.
Notez le caractère :
compris entre client_id
et client_secret
.
Corps de requête¶
Paramètre |
Type de données |
Obligatoire |
Description |
---|---|---|---|
|
Chaîne |
Oui |
Type d’autorisation demandée : . |
|
Chaîne |
Oui |
Code d’autorisation renvoyé par le point de terminaison du jeton. Utilisé et requis lorsque |
|
Chaîne |
Oui |
Jeton d’actualisation renvoyé par une demande antérieure au point de terminaison du jeton lors de l’utilisation du code d’autorisation. Utilisé et requis lorsque |
|
Chaîne |
Oui |
URI de redirection comme utilisée dans l’URL d’autorisation lors de la demande d’un code d’autorisation. Utilisé et requis lorsque |
|
Chaîne |
Non |
Requis uniquement si la demande d’autorisation a été envoyée au point de terminaison d’autorisation avec une valeur de paramètre |
Réponse¶
Un objet JSON est renvoyé avec les champs suivants :
Champ |
Type de données |
Description |
---|---|---|
|
Chaîne |
Jeton d’accès utilisé pour établir une session Snowflake |
|
Chaîne |
Jeton d’actualisation. Non émis si le client est configuré pour ne pas émettre de jetons d’actualisation ou si l’utilisateur n’a pas consenti à la portée |
|
Entier |
Nombre de secondes restantes jusqu’à l’expiration du jeton |
|
Chaîne |
Type de jeton d’accès. Actuellement, toujours |
|
Chaîne |
Nom d’utilisateur auquel appartient le jeton d’accès. Actuellement renvoyé uniquement lors de l’échange d’un code d’autorisation pour un jeton d’accès. |
Exemple de réponse aboutie¶
L’exemple suivant montre une réponse réussie lors de l’échange d’un code d’autorisation contre un jeton d’accès et d’actualisation :
{
"access_token": "ACCESS_TOKEN",
"expires_in": 600,
"refresh_token": "REFRESH_TOKEN",
"token_type": "Bearer",
"username": "user1",
}
Exemple de réponse infructueuse¶
L’exemple suivant montre une réponse infructueuse :
{
"data" : null,
"message" : "This is an invalid client.",
"code" : null,
"success" : false,
"error" : "invalid_client"
}
La valeur de chaîne message
est une description de l’erreur, et error
correspond au type d’erreur. Pour plus d’informations sur les types d’erreurs renvoyées, voir Codes d’erreur OAuth.
Clé de preuve pour l’échange de code¶
Snowflake prend en charge la clé de vérification pour l’échange de code (PKCE) afin d’obtenir des jetons d’accès à l’aide du type d’octroi authorization_code
, comme décrit dans RFC 7636. PKCE peut être utilisé pour réduire le risque d’attaque par interception de code d’autorisation et convient aux clients qui ne sont peut-être pas en mesure de protéger complètement le secret du client.
Par défaut, PKCE est facultatif et n’est appliqué que si les paramètres code_challenge
et code_challenge_method
sont tous deux inclus dans l’URL du point de terminaison d’autorisation. Cependant, Snowflake conseille vivement à votre client d’exiger PKCE pour toutes les autorisations afin de sécuriser davantage le flux de données OAuth.
Ce qui suit décrit le fonctionnement de PKCE pour Snowflake :
Le client crée un secret appelé vérificateur de code et y effectue une transformation pour générer le défi de code. Le client garde le secret.
Important
Générez le vérificateur de code à partir des caractères ASCII autorisés conformément à la Section 4.1 de RFC 7636.
Le client qui dirige l’utilisateur vers l’URL d’autorisation ajoute les deux paramètres de requête suivants :
code_challenge
Spécifie le défi de code généré à l’étape 1.
code_challenge_method
Spécifie les transformations utilisées sur le vérificateur de code à l’étape 1 pour générer le défi de code. Actuellement, Snowflake ne prend en charge que SHA256. Cette valeur doit donc être définie sur
S256
. L’algorithme de transformation pour SHA256 estBASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
.
Une fois que l’utilisateur a accepté les portées demandées ou que Snowflake a déterminé que le consentement est présent pour cet utilisateur, le code d’autorisation est émis.
Le client reçoit le code d’autorisation du serveur d’autorisation Snowflake, qu’il soumet ensuite avec le
code_verifier
dans la demande au point de terminaison du jeton.Snowflake transforme la valeur
code_verifier
et vérifie que la valeur transformée correspond à la valeurcode_challenge
utilisée lors de la génération d’autorisations. Si ces valeurs correspondent, le serveur d’autorisation émet les jetons d’accès et d’actualisation.
Utilisation de l’authentification par paire de clés¶
Snowflake accepte l’authentification par paire de clés plutôt que l’authentification par nom d’utilisateur/mot de passe typique lors de l’appel vers un point de terminaison de jeton OAuth. Cette méthode d’authentification nécessite une paire de clés de 2048 bits (minimum) RSA. Générez la paire de clés publiques-privées PEM (Privacy Enhanced Mail) via OpenSSL. La clé publique est attribuée à l’utilisateur Snowflake qui utilisera le client Snowflake.
Pour configurer la paire de clés publiques/privées :
Depuis la ligne de commande d’une fenêtre de terminal, générez une clé privée chiffrée.
$ openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out rsa_key.p8
OpenSSL demande une phrase secrète utilisée pour chiffrer le fichier de la clé privée. Snowflake recommande d’utiliser une phrase secrète forte pour protéger la clé privée. Enregistrez cette phrase secrète. Vous devez l’entrer lorsque vous vous connectez à Snowflake. Notez que la phrase secrète n’est utilisée que pour protéger la clé privée et n’est jamais envoyée à Snowflake.
Exemple de clé privée PEM
-----BEGIN ENCRYPTED PRIVATE KEY----- MIIE6TAbBgkqhkiG9w0BBQMwDgQILYPyCppzOwECAggABIIEyLiGSpeeGSe3xHP1 wHLjfCYycUPennlX2bd8yX8xOxGSGfvB+99+PmSlex0FmY9ov1J8H1H9Y3lMWXbL ... -----END ENCRYPTED PRIVATE KEY-----
Depuis la ligne de commande, générez la clé publique en faisant référence à la clé privée :
$ openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
Exemple de clé publique PEM
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy+Fw2qv4Roud3l6tjPH4 zxybHjmZ5rhtCz9jppCV8UTWvEXxa88IGRIHbJ/PwKW/mR8LXdfI7l/9vCMXX4mk ... -----END PUBLIC KEY-----
Copiez les fichiers de clés publiques et privées dans un répertoire local en vue de leur stockage. Enregistrez le chemin d’accès aux fichiers.
Notez que la clé privée est stockée au format PKCS#8 (Public Key Cryptography Standards) et est chiffrée à l’aide de la phrase de chiffrement que vous avez spécifiée à l’étape précédente ; toutefois, le fichier doit toujours être protégé contre tout accès non autorisé au moyen du mécanisme d’autorisation de fichier fourni par votre système d’exploitation. Il est de votre responsabilité de sécuriser le fichier lorsqu’il n’est pas utilisé.
Attribuez la clé publique à l’objet d’intégration à l’aide de ALTER SECURITY INTEGRATION. Par exemple :
ALTER SECURITY INTEGRATION myint SET OAUTH_CLIENT_RSA_PUBLIC_KEY='MIIBIjANBgkqh...';
Note
Seuls les administrateurs de compte peuvent exécuter la commande ALTER SECURITY INTEGRATION.
Excluez l’en-tête et le pied de page de la clé publique dans la commande.
Vérifiez l’empreinte de la clé publique en utilisant DESCRIBE INTEGRATION :
DESC SECURITY INTEGRATION myint; +----------------------------------+---------------+----------------------------------------------------------------------+------------------+ | property | property_type | property_value | property_default | |----------------------------------+---------------+----------------------------------------------------------------------+------------------| ... | OAUTH_CLIENT_RSA_PUBLIC_KEY_FP | String | SHA256:MRItnbO/123abc/abcdefghijklmn12345678901234= | | | OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP | String | | | ... +----------------------------------+---------------+----------------------------------------------------------------------+------------------+
Note
La propriété
OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP
est décrite dans Rotation de clé (dans ce chapitre).Modifiez et exécutez l’exemple de code ci-dessous. Le code utilise la clé privée pour coder un JWT et transmet ensuite ce jeton au serveur d’autorisation de Snowflake :
Mettez à jour les paramètres de sécurité :
<clé_privée>
: ouvrez le fichierrsa_key.p8
dans un éditeur de texte et copiez les lignes entre l’en-têteBEGIN
et le pied de pageEND
.
Mettez à jour les paramètres de session :
<account_identifier>
: spécifie le nom complet de votre compte (fourni par Snowflake).
Mettez à jour les champs de jetons Web (JWT) JSON :
- post body
Un objet JSON avec les champs standards suivants (« revendications ») :
Attribut
Type de données
Obligatoire
Description
iss
Chaîne
Oui
Spécifie le principal qui a émis le JWT au format
client_id.public_key_fp
oùclient_id
est l’ID de client de l’intégration du client OAuth etpublic_key_fp
est l’empreinte de la clé publique utilisée lors de la vérification.sub
Chaîne
Oui
Objet du JWT au format
account_identifier.client_id
oùaccount_identifier
est le nom complet du compte Snowflake etclient_id
est l’ID du client de l’intégration du client OAuth. Selon la plate-forme Cloud (AWS ou Azure) et la région où votre compte est hébergé, le nom complet du compte peut nécessiter des segments supplémentaires. Pour plus d’informations, voir la description de la variableaccount
sous Point de terminaison de jeton.iat
Horodatage
Non
Heure à laquelle le jeton a été émis.
exp
Horodatage
Oui
Heure à laquelle le jeton doit expirer. Cette période devrait être relativement courte (quelques minutes, par exemple).
Exemple de code
Notez que la valeur
private_key
inclut l’en-tête-----BEGIN
et le pied de page-----END
.import datetime import json import urllib import jwt import requests private_key = """ <private_key> """ public_key_fp = "SHA256:MR..." def _make_request(payload, encoded_jwt_token): token_url = "https://<account_identifier>.snowflakecomputing.com/oauth/token-request" headers = { u'Authorization': "Bearer %s" % (encoded_jwt_token), u'content-type': u'application/x-www-form-urlencoded' } r = requests.post( token_url, headers=headers, data=urllib.urlencode(payload)) return r.json() def make_request_for_access_token(oauth_az_code, encoded_jwt_token): """ Given an Authorization Code, make a request for an Access Token and a Refresh Token.""" payload = { 'grant_type': 'authorization_code', 'code': oauth_az_code } return _make_request(payload, encoded_jwt_token) def make_request_for_refresh_token(refresh_token, encoded_jwt_token): """ Given a Refresh Token, make a request for another Access Token.""" payload = { 'grant_type': 'refresh_token', 'refresh_token': refresh_token } return _make_request(payload, encoded_jwt_token) def main(): account_identifier = "<account_identifier>" client_id = "1234" # found by running DESC SECURITY INTEGRATION issuer = "{}.{}".format(client_id, public_key_fp) subject = "{}.{}".format(account_identifier, client_id) payload = { 'iss': issuer, 'sub': subject, 'iat': datetime.datetime.utcnow(), 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=30) } encoded_jwt_token = jwt.encode( payload, private_key, algorithm='RS256') data = make_request_for_access_token(oauth_az_code, encoded_jwt_token) refresh_token = data['refresh_token'] data = make_request_for_refresh_token(refresh_token, encoded_jwt_token) access_token = data['access_token'] if __name__ == '__main__': main()
Une fois le jeton créé, envoyez-le dans des demandes vers le point de terminaison du jeton. Les demandes requièrent le format d’autorisation Bearer comme en-tête d’autorisation au lieu du format d’autorisation de base normalement utilisé pour l’ID du client et le secret du client, comme suit :
"Authorization: Bearer JWT_TOKEN"
Rotation de clés¶
Snowflake accepte plusieurs clés actives pour permettre une rotation ininterrompue. Faites pivoter et remplacez vos clés publiques et privées en fonction du calendrier d’expiration que vous suivez en interne.
Actuellement, vous pouvez utiliser les paramètres OAUTH_CLIENT_RSA_PUBLIC_KEY
et OAUTH_CLIENT_RSA_PUBLIC_KEY_2
pour ALTER SECURITY INTEGRATION afin d’associer jusqu’à 2 clés publiques à un seul utilisateur.
Pour faire tourner vos clés :
Effectuez les étapes de la section Utilisation de l’authentification par paire de clés (dans cette rubrique) :
Générer un nouvel ensemble de clés privées et publiques.
Attribuer la clé publique à l’intégration. Définir la valeur de la clé publique sur
OAUTH_CLIENT_RSA_PUBLIC_KEY
ouOAUTH_CLIENT_RSA_PUBLIC_KEY_2
(la valeur de la clé qui n’est pas actuellement utilisée). Par exemple :alter integration myint set oauth_client_rsa_public_key_2='JERUEHtcve...';
Mettez à jour le code pour vous connecter à Snowflake. Spécifiez la nouvelle clé privée.
Snowflake vérifie la bonne clé publique active pour l’authentification sur la base de la clé privée soumise.
Retirez l’ancienne clé publique de l’intégration. Par exemple :
alter integration myint unset oauth_client_rsa_public_key;
Codes d’erreur¶
Voir les Codes d’erreur pour une liste de codes d’erreur associés à OAuth, ainsi que les erreurs qui sont renvoyées dans le blob JSON, pendant le flux d’autorisation, la demande ou l’échange de jetons, ou lors de la création d’une session Snowflake après avoir terminé le flux OAuth.