서버에 인증하기¶
이 항목에서는 Snowflake SQL API를 사용할 때 서버를 인증하는 방법에 대해 설명합니다.
요청을 보낼 때 요청에 인증 정보가 포함되어야 합니다. 다음 섹션에서는 이 정보를 요청에 추가하는 방법을 설명합니다.
이 항목의 내용:
OAuth 사용하기¶
OAuth를 사용하려면 다음 단계를 수행하십시오.
인증을 위해 OAuth를 설정합니다.
OAuth를 설정하고 OAuth 토큰을 가져오는 방법에 대한 자세한 내용은 OAuth 소개 를 참조하십시오.
생성된 OAuth 토큰을 사용하여 Snowflake에 연결할 수 있는지 SnowSQL을 사용하여 확인합니다.
Linux 및 MacOS 시스템의 경우
$ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token=<oauth_token>
Windows 시스템의 경우
$ snowsql -a <account_identifier> -u <user> --authenticator=oauth --token="<oauth_token>"
보내는 각 API 요청에서 다음 헤더를 설정합니다.
Authorization: Bearer oauth_token
여기서
oauth_token
은 생성된 OAuth 토큰입니다.X-Snowflake-Authorization-Token-Type: OAUTH
X-Snowflake-Authorization-Token-Type
헤더를 생략하도록 선택할 수도 있습니다. 이 헤더가 없으면 Snowflake는Authorization
헤더의 토큰이 OAuth 토큰이라고 가정합니다.
키 페어 인증 사용하기¶
키 페어 인증을 사용하려면 다음 단계를 수행하십시오.
키 페어 인증을 설정합니다.
이 프로세스의 일부로서 다음을 수행해야 합니다.
공개-개인 키 페어를 생성합니다. 생성된 개인 키는 파일(예: 이름이
rsa_key.p8
인 파일)에 있어야 합니다.Snowflake 사용자에게 공개 키를 할당합니다. 사용자에게 키를 할당한 후 DESCRIBE USER 명령을 실행합니다. 출력에서
RSA_PUBLIC_KEY_FP
속성은 사용자에게 할당된 공개 키의 지문으로 설정되어야 합니다.
키 페어를 생성하고 사용자에게 키를 할당하는 방법에 대한 지침은 키 페어 인증 및 키 페어 순환 을 참조하십시오. 지문 생성과 JWT 토큰 생성의 언어별 예시는 다음을 참조하십시오.
생성된 개인 키를 사용하여 Snowflake에 연결 할 수 있는지 SnowSQL을 사용하여 확인합니다.
$ snowsql -a <account_identifier> -u <user> --private-key-path <path>/rsa_key.p8
암호화된 개인 키를 생성한 경우, SnowSQL은 키 생성 시 만든 암호 구문을 입력하라는 메시지를 표시합니다.
애플리케이션 코드에서:
사용자에 대한 공개 키의 지문(SHA-256 해시)을 생성합니다. 지문에
SHA256:
접두사를 붙입니다. 예:SHA256:hash
SQL DESCRIBE USER 명령을 실행하여 RSA_PUBLIC_KEY_FP 속성에서 값을 가져올 수도 있습니다.
페이로드에서 다음 필드를 사용하여 JSON 웹 토큰(JWT) 을 생성합니다.
필드
설명
예
iss
JWT의 발급자입니다. 이를 다음 값으로 설정합니다.
account_identifier.user.SHA256:public_key_fingerprint
여기서,
account_identifier
는 Snowflake 계정 식별자 입니다.계정 로케이터 를 사용하는 경우 계정 로케이터에서 모든 리전 정보를 제외하십시오.
user
는 Snowflake 사용자 이름입니다.SHA256:public_key_fingerprint
는 이전 단계에서 생성한 지문입니다.
참고
The
account_identifier
anduser
values must use all uppercase characters. 계정 ID에 마침표(.
)가 포함된 경우 계정 식별자의 마침표로 인해 JWT가 유효하지 않게 되므로 마침표를 하이픈(-
)으로 바꿔야 합니다.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
(밀리초)보내는 각 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
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))
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')
Java 예제¶
Java에서 JWT를 생성하는 예제는 SimpleStatementsApi.java
를 참조하십시오.
참고
이 예는 참조용으로만 제공되는 예입니다. 프로덕션 애플리케이션 또는 환경에서는 이 코드를 사용하지 마십시오.
이 예제에서는 다음 서드 파티 라이브러리를 사용합니다.
Swagger Codegen: REST API 및 애플리케이션 개발에 유용한 오픈 소스 라이브러리입니다.
Auth0: 인증과 JWT 토큰 생성을 위해 Java API를 제공합니다.
Node.js 예제¶
Node.js에서 JWT를 생성하는 예제는 sql-api-generate-jwt.js
를 참조하십시오.
참고
이 예는 참조용으로만 제공되는 예입니다. 프로덕션 애플리케이션 또는 환경에서는 이 코드를 사용하지 마십시오.