サーバーへの認証¶
このトピックでは、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 Webトークン(JWT) を生成します。
フィールド
説明
例
iss
JWT の発行者。次の値に設定します。
account_identifier.user.SHA256:public_key_fingerprint
条件:
account_identifier
は、Snowflakeの使用する アカウント識別子 です。アカウントロケーター を使用している場合は、アカウントロケーターからリージョン情報を除外します。
user
は、Snowflakeユーザー名です。SHA256:public_key_fingerprint
は、前のステップで生成したフィンガープリントです。
注釈
account_identifier
とuser
の値は、すべて大文字を使用する必要があります。アカウント 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 APIsとアプリケーションの開発に役立つオープンソースライブラリ。
Auth0: 認証と JWT トークンの生成にJava APIs を提供。
Node.jsの例¶
Node.jsで JWT を生成する例については、 sql-api-generate-jwt.js
をご参照ください。
注釈
この例は、参照としてのみ使用することを目的としています。このコードは、実稼働アプリケーションまたは環境では使用しないでください。