서버에 인증하기

이 항목에서는 Snowflake SQL API를 사용할 때 서버를 인증하는 방법에 대해 설명합니다.

요청을 보낼 때 요청에 인증 정보가 포함되어야 합니다. 다음 섹션에서는 이 정보를 요청에 추가하는 방법을 설명합니다.

이 항목의 내용:

OAuth 사용하기

OAuth를 사용하려면 다음 단계를 수행하십시오.

  1. 인증을 위해 OAuth를 설정합니다.

    OAuth를 설정하고 OAuth 토큰을 가져오는 방법에 대한 자세한 내용은 OAuth 소개 를 참조하십시오.

  2. 생성된 OAuth 토큰을 사용하여 Snowflake에 연결할 수 있는지 SnowSQL을 사용하여 확인합니다.

    • Linux 및 MacOS 시스템의 경우

    $ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token=<oauth_token>
    
    Copy
    • Windows 시스템의 경우

    $ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token="<oauth_token>"
    
    Copy
  3. 보내는 각 API 요청에서 다음 헤더를 설정합니다.

    • Authorization: Bearer oauth_token

      여기서 oauth_token 은 생성된 OAuth 토큰입니다.

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

      X-Snowflake-Authorization-Token-Type 헤더를 생략하도록 선택할 수도 있습니다. 이 헤더가 없으면 Snowflake는 Authorization 헤더의 토큰이 OAuth 토큰이라고 가정합니다.

키 페어 인증 사용하기

키 페어 인증을 사용하려면 다음 단계를 수행하십시오.

  1. 키 페어 인증을 설정합니다.

    이 프로세스의 일부로서 다음을 수행해야 합니다.

    1. 공개-개인 키 페어를 생성합니다. 생성된 개인 키는 파일(예: 이름이 rsa_key.p8 인 파일)에 있어야 합니다.

    2. Snowflake 사용자에게 공개 키를 할당합니다. 사용자에게 키를 할당한 후 DESCRIBE USER 명령을 실행합니다. 출력에서 RSA_PUBLIC_KEY_FP 속성은 사용자에게 할당된 공개 키의 지문으로 설정되어야 합니다.

    키 페어를 생성하고 사용자에게 키를 할당하는 방법에 대한 지침은 키 페어 인증 및 키 페어 순환 을 참조하십시오. 지문 생성과 JWT 토큰 생성의 언어별 예시는 다음을 참조하십시오.

  2. 생성된 개인 키를 사용하여 Snowflake에 연결 할 수 있는지 SnowSQL을 사용하여 확인합니다.

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

    암호화된 개인 키를 생성한 경우, SnowSQL은 키 생성 시 만든 암호 구문을 입력하라는 메시지를 표시합니다.

  3. 애플리케이션 코드에서:

    1. 사용자에 대한 공개 키의 지문(SHA-256 해시)을 생성합니다. 지문에 SHA256: 접두사를 붙입니다. 예:

      SHA256:hash

      SQL DESCRIBE USER 명령을 실행하여 RSA_PUBLIC_KEY_FP 속성에서 값을 가져올 수도 있습니다.

    2. 페이로드에서 다음 필드를 사용하여 JSON 웹 토큰(JWT) 을 생성합니다.

      필드

      설명

      iss

      JWT의 발급자입니다. 이를 다음 값으로 설정합니다.

      account_identifier.user.SHA256:public_key_fingerprint

      여기서,

      • account_identifier 는 Snowflake 계정 식별자 입니다.

        계정 로케이터 를 사용하는 경우 계정 로케이터에서 모든 리전 정보를 제외하십시오.

      • user 는 Snowflake 사용자 이름입니다.

      • SHA256:public_key_fingerprint 는 이전 단계에서 생성한 지문입니다.

      참고

      The account_identifier and user values must use all uppercase characters.

      MYORGANIZATION-MYACCOUNT.MYUSER.SHA256:public_key_fingerprint

      sub

      JWT의 제목입니다. 이를 다음 값으로 설정합니다.

      account_identifier.user

      MYORGANIZATION-MYACCOUNT.MYUSER

      iat

      JWT의 발급 시간(UTC)입니다. 값을 초 또는 밀리초 단위의 현재 시간 값으로 설정합니다.

      1615370644 (초) . 1615370644000 (밀리초)

      exp

      JWT의 만료 시간(UTC)입니다. 값을 초 또는 밀리초 단위로 지정할 수 있습니다.

      참고

      JWT는 만료 시간을 더 길게 지정하더라도 토큰 발급 후 최대 1시간 동안 유효합니다.

      1615374184 (초) . 1615374184000 (밀리초)

    3. 보내는 각 API 요청에서 다음 헤더를 설정합니다.

      • Authorization: Bearer JWT

        여기서 JWT 는 생성한 토큰입니다.

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

Python 예제

다음 섹션에서는 Python을 사용하여 JWT와 지문을 생성하는 방법을 설명합니다.

Python에서 JWT를 생성하는 예는 sql-api-generate-jwt.py 를 참조하십시오. sql-api-generate-jwt.py 예에서는 다음을 실행하여 설치할 수 있는 PyJWT 모듈 을 사용합니다.

pip install pyjwt
Copy

Python으로 JWT 생성하기

다음 코드 섹션은 JWT를 생성하는 방법을 보여줍니다. 전체 예는 sql-api-generate-jwt.py 를 참조하십시오.

참고

이 예는 참조용으로만 제공되는 예입니다. 프로덕션 애플리케이션 또는 환경에서는 이 코드를 사용하지 마십시오.

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

Python으로 지문 생성하기

다음 코드 섹션은 지문을 생성하는 방법을 보여줍니다. 전체 예는 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 예제

Java에서 JWT를 생성하는 예제는 SimpleStatementsApi.java 를 참조하십시오.

참고

이 예는 참조용으로만 제공되는 예입니다. 프로덕션 애플리케이션 또는 환경에서는 이 코드를 사용하지 마십시오.

이 예제에서는 다음 서드 파티 라이브러리를 사용합니다.

  • Swagger Codegen: REST API 및 애플리케이션 개발에 유용한 오픈 소스 라이브러리입니다.

  • Auth0: 인증과 JWT 토큰 생성을 위해 Java API를 제공합니다.

Node.js 예제

Node.js에서 JWT를 생성하는 예제는 sql-api-generate-jwt.js 를 참조하십시오.

참고

이 예는 참조용으로만 제공되는 예입니다. 프로덕션 애플리케이션 또는 환경에서는 이 코드를 사용하지 마십시오.