Autenticação no servidor¶
Este tópico descreve como fazer a autenticação no servidor ao usar a API de SQL do Snowflake.
Quando você envia uma solicitação, a solicitação deve incluir informações de autenticação. As próximas seções explicam como adicionar essas informações à solicitação:
Neste tópico:
Uso de OAuth¶
Para usar o OAuth, siga estes passos:
- Configure o OAuth para a autenticação. - Consulte Introdução ao OAuth para obter detalhes sobre como configurar o OAuth e obter um token OAuth. 
- Use o Snowflake CLI para verificar se você pode usar um token OAuth gerado para se conectar ao Snowflake: - Para sistemas Linux e MacOS 
 - $ snow connection test --account <account_identifier> --user <user> --authenticator=oauth --token=<oauth_token> - Para sistemas Windows 
 - $ snow connection test --account <account_identifier> --user <user> --authenticator=oauth --token=<oauth_token> 
- Em cada solicitação de API que você enviar, defina os seguintes cabeçalhos: - Authorization: Bearer oauth_token- onde - oauth_tokené o token OAuth gerado.
- (Opcional) - X-Snowflake-Authorization-Token-Type: OAUTH- Se você omitir o cabeçalho - X-Snowflake-Authorization-Token-Type, o Snowflake determinará o tipo de token examinando o token.- Embora esse cabeçalho seja opcional, você pode optar por especificá-lo. Você pode definir o cabeçalho com um dos seguintes valores: - KEYPAIR_JWT(para autenticação de pares de chaves)
- OAUTH(para OAuth)
- PROGRAMMATIC_ACCESS_TOKEN(para tokens de acesso programático)
 
 
Uso de autenticação de pares de chaves¶
Para usar a autenticação por par de chaves, siga esses passos:
- Configure a autenticação por par de chaves. - Como parte desse processo, você deve: - Gerar um par de chaves público-privado. A chave privada gerada deve estar em um arquivo (por exemplo, chamado - rsa_key.p8).
- Atribua a chave pública a seu usuário do Snowflake. Depois de atribuir a chave ao usuário, execute o comando DESCRIBE USER. Na saída, a propriedade - RSA_PUBLIC_KEY_FPdeve ser definida como a impressão digital da chave pública atribuída ao usuário.
 - Para obter instruções sobre como gerar o par de chaves e atribuir uma chave a um usuário, consulte Autenticação de pares de chaves e rotação de pares de chaves. Para exemplos específicos de como criar uma impressão digital e gerar um token JWT, veja o seguinte: 
- Use o Snowflake CLI para verificar se você pode usar a chave privada gerada para conectar ao Snowflake: - $ snow connection generate-jwt --account <account_identifier> --user <user> --private-key-path <path>/rsa_key.p8 - O comando solicita uma senha de chave privada para concluir a conexão. É possível evitar o prompt fornecendo a frase secreta na variável de ambiente - PRIVATE_KEY_PASSPHRASE.
- Em seu código do aplicativo: - Gere a impressão digital (um hash SHA-256) da chave pública para o usuário. Prefixe a impressão digital com - SHA256:. Por exemplo:- SHA256:hash- Você também pode executar o comando SQL DESCRIBE USER para obter o valor da propriedade RSA_PUBLIC_KEY_FP. 
- Gere um web token JSON (JWT) com os seguintes campos na carga útil: - Campo - Descrição - Exemplo - iss- Emissor do JWT. Defina-o com o seguinte valor: - account_identifier.user.SHA256:public_key_fingerprint- onde: - account_identifieré seu identificador da conta Snowflake.- Se você estiver usando o localizador de contas, exclua qualquer informação de região do localizador de contas. 
- useré seu nome de usuário Snowflake.
- SHA256:public_key_fingerprinté a impressão digital que você gerou na etapa anterior.
 - Nota - Os valores - account_identifiere- userdevem usar todos os caracteres maiúsculos. Se seu ID da conta contiver pontos (- .), você deverá substituí-los por hífens (- -), pois os pontos em um identificador de conta fazem com que JWT seja inválido.- MYORGANIZATION-MYACCOUNT.MYUSER.SHA256:public_key_fingerprint- sub- Assunto do JWT. Defina-o com o seguinte valor: - account_identifier.user- MYORGANIZATION-MYACCOUNT.MYUSER- iat- Tempo de emissão do JWT em UTC. Defina o valor como o valor de tempo atual como segundos ou milissegundos. - 1615370644(segundos) .- 1615370644000(milissegundos)- exp- Tempo de expiração do JWT em UTC. Você pode especificar o valor como segundos ou milissegundos. - Nota - Nota: o JWT é válido por, no máximo, uma hora após a emissão do token, mesmo se você especificar um tempo de vencimento mais longo. - 1615374184(segundos) .- 1615374184000(milissegundos)
- Em cada solicitação de API que você enviar, defina os seguintes cabeçalhos: - Authorization: Bearer JWT- onde - JWTé o token que você gerou.
- (Opcional) - X-Snowflake-Authorization-Token-Type: KEYPAIR_JWT- Se você omitir o cabeçalho - X-Snowflake-Authorization-Token-Type, o Snowflake determinará o tipo de token examinando o token.- Embora esse cabeçalho seja opcional, você pode optar por especificá-lo. Você pode definir o cabeçalho com um dos seguintes valores: - KEYPAIR_JWT(para autenticação de pares de chaves)
- OAUTH(para OAuth)
- PROGRAMMATIC_ACCESS_TOKEN(para tokens de acesso programático)
 
 
 
Exemplo em Python¶
As seções a seguir descrevem como gerar um JWT e uma impressão digital usando Python.
Para um exemplo de geração de um JWT em Python, veja sql-api-generate-jwt.py. O exemplo sql-api-generate-jwt.py usa o módulo PyJWT, que você pode instalar executando:
pip install pyjwt
Como gerar um JWT em Python¶
As seções de código a seguir demonstram como gerar um JWT. Para obter um exemplo completo, consulte sql-api-generate-jwt.py.
Nota
Este exemplo se destina a ser utilizado apenas como referência. Não utilize esse código em aplicativos ou ambientes de produção.
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))
Como gerar uma impressão digital em Python¶
As seções de código a seguir demonstram como gerar a impressão digital. Para obter um exemplo completo, consulte 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')
Exemplo de Snowflake CLI¶
Você pode usar o comando Snowflake CLI snow connection generate-jwt para gerar um JWT para autenticação de pares de chaves. Para obter mais informações, consulte snow connection generate-jwt.
Este exemplo gera um token para a conta TEST e usuário JDOE, usando a chave privada de rsa_key.p8:
snow connection generate-jwt --user JDOE --account TEST --private-key-file=rsa_key.p8
O comando solicita uma senha de chave privada para concluir a conexão. É possível evitar o prompt fornecendo a frase secreta na variável de ambiente PRIVATE_KEY_PASSPHRASE.
Exemplo em Java¶
Para obter um exemplo de geração de um JWT em Java, consulte SimpleStatementsApi.java.
Nota
Este exemplo se destina a ser utilizado apenas como referência. Não utilize esse código em aplicativos ou ambientes de produção.
Esse exemplo usa as seguintes bibliotecas de terceiros:
- Swagger Codegen: uma biblioteca de código aberto útil no desenvolvimento de REST APIs e aplicativos. 
- Auth0: fornece APIs de Java para autenticação e geração de tokens JWT. 
Exemplo em Node.js¶
Para um exemplo de geração de um JWT em Node.js, veja sql-api-generate-jwt.js.
Nota
Este exemplo se destina a ser utilizado apenas como referência. Não utilize esse código em aplicativos ou ambientes de produção.