mssql-python での Microsoft Entra 認証

Microsoft Entra IDは、mssql-pythonドライバーを通じてAzure SQL Database、Azure SQL Managed Instance、およびMicrosoft FabricのSQLデータベースに対して、IDベースの認証を提供します。 Microsoft Entra認証はSQL認証よりも以下の機能を提供します:

  • Microsoft Entra IDを使った集中型のアイデンティティ管理。
  • パスワードの必要性を排除するトークンベースの認証。
  • 条件付きアクセスポリシーのサポート。
  • Azure でホストされるアプリケーション向けのマネージド ID

mssql-pythonドライバは7つのMicrosoft Entra認証モードをサポートしており、すべてAuthentication 接続文字列キーワードで設定されています。

認証モード

接続文字列のAuthenticationキーワードを以下のいずれかに設定してください:

認証値 説明
ActiveDirectoryDefault DefaultAzureCredentialを使い、複数の方法を自動的に試します。
ActiveDirectoryInteractive ブラウザベースのインタラクティブサインイン。
ActiveDirectoryDeviceCode https://microsoft.com/devicelogin にコードを入力します。
ActiveDirectoryPassword Microsoft Entra ID を使用したユーザー名とパスワード。 廃止。
ActiveDirectoryMSI マネージド・アイデンティティ(システム割り当てまたはユーザー割り当て)。
ActiveDirectoryServicePrincipal サービスプリンシパルで、クライアントIDと秘密情報付きです。
ActiveDirectoryIntegrated WindowsはMicrosoft Entra ID(Kerberos)と統合されています。

Note

ActiveDirectoryDefaultActiveDirectoryInteractiveActiveDirectoryDeviceCodeの各モードにはazure-identityパッケージが必要です。 pip install azure-identityと共にインストールします。

DefaultAzureCredential

ActiveDirectoryDefaultモードはAzure Identity SDKのDefaultAzureCredentialを使用し、以下の認証方法を順番に試します。

  1. 環境変数。
  2. Kubernetesのワークロード識別子。
  3. マネージド ID。
  4. Azure CLI の資格情報
  5. Azure PowerShell の資格情報
  6. Azure Developer CLI の資格情報
  7. インタラクティブブラウザが有効なら。

例:デフォルト認証

以下の例は ActiveDirectoryDefaultと接続しており、 DefaultAzureCredential チェーンを使って有効な認証情報を自動的に検出します。

import mssql_python

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
)

cursor = conn.cursor()
cursor.execute("SELECT USER_NAME()")
print(f"Connected as: {cursor.fetchval()}")

このモードはローカル開発に使うと、Azure CLIの認証情報を自動的に取得します。 本番環境では、特定の認証モード(ActiveDirectoryMSIActiveDirectoryServicePrincipal)を使いましょう。 DefaultAzureCredential 最初の接続ごとに複数の認証情報提供者を経由するため、本番ワークロードには不要な遅延が生じます。

対話型認証

インタラクティブなアプリケーションの場合は、ブラウザベースの認証を使いましょう。 ユーザーは CREATE USER [user@domain.com] FROM EXTERNAL PROVIDERで作成されたデータベースアカウントを持っている必要があります。 完全な前提条件については、「Microsoft Entra認証の設定」を参照してください。

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryInteractive;"
    "Encrypt=yes;"
)

Windowsでは、このモードはODBCドライバーのネイティブなインタラクティブフローに委譲されます。 他のプラットフォームでは、Azure Identity SDKのブラウザベースの認証を使用しています。

デバイス コード認証

ブラウザがない環境、例えばSSHセッションやコンテナにはデバイスコード認証を使用してください。 ユーザーは CREATE USER [user@domain.com] FROM EXTERNAL PROVIDERで作成されたデータベースアカウントを持っている必要があります。 前提条件については、「Microsoft Entra認証の設定」を参照してください。

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDeviceCode;"
    "Encrypt=yes;"
)
# Output: To sign in, use a web browser to open https://microsoft.com/devicelogin
# and enter the code XXXXXXX to authenticate.

別のデバイスのブラウザで認証するプロンプトに従ってください。

サービスプリンシパル認証

ユーザー操作を必要としない自動化アプリケーションにはサービスプリンシパル認証を活用してください:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryServicePrincipal;"
    "UID=<client-id>;"       # Application (client) ID
    "PWD=<client-secret>;"   # Client secret
    "Encrypt=yes;"
)

サービスプリンシパルの作成

  1. Microsoft Entra IDでアプリケーションを登録します
  2. クライアント シークレットを作成します。
  3. サービスプリンシパルにデータベースへのアクセスを許可する:
-- In Azure SQL
CREATE USER [app-name] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [app-name];
ALTER ROLE db_datawriter ADD MEMBER [app-name];

ヒント

エラー33131(表示名の重複)で失敗した場合は、CREATE USERAzureポータルのWITH OBJECT_IDページ(アプリ登録ページではなく)からサービスプリンシパルのオブジェクトIDを指定するを使います。

CREATE USER [app-name] FROM EXTERNAL PROVIDER
    WITH OBJECT_ID = '<enterprise-app-object-id>';

詳細は、Microsoft Entraログインおよび非ユニークな表示名を持つユーザーについてご参照ください。

マネージド ID

Azureホストアプリケーション(App Service、Azure Functions、VMなど)にはマネージドID認証を使用してください:

システムによって割り当てられた管理ID

Azureリソースに直接割り当てられたアイデンティティを使って接続してください:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryMSI;"
    "Encrypt=yes;"
)

ユーザー指定のマネージド ID

UIDフィールドでユーザー割り当て管理IDのクライアントIDを指定します:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryMSI;"
    "UID=<managed-identity-client-id>;"
    "Encrypt=yes;"
)

データベースアクセスの設定

データベースでマネージドIDのアクセス権を付与してください。 外部ユーザーを作成するには、サーバー上でMicrosoft Entra管理者を設定する必要があります。 Azureリソースでマネージドアイデンティティを有効にするには、「Azureリソースの管理されたアイデンティティ」をご覧ください。

-- Replace 'my-app-service' with your Azure resource name
CREATE USER [my-app-service] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [my-app-service];
ALTER ROLE db_datawriter ADD MEMBER [my-app-service];

パスワード認証(廃止)

Important

Microsoft SQL ドライバーでは、ActiveDirectoryPassword 認証オプション (Microsoft Entra ID パスワード認証) は非推奨です。 このリスクの高い認証フローは、必須のMicrosoft Entra多要素認証 (MFA) と互換性がありません。MFA が適用されているテナントでは機能しない可能性があります。 別のMicrosoft Entra認証方法への移行を計画します。

Microsoft Entra IDパスワード認証は、OAuth 2.0 リソース所有者パスワード資格情報 (ROPC) の付与に基づいています。これにより、アプリケーションは自分のパスワードを直接処理してユーザーにサインインできます。

MICROSOFTでは、MFA と互換性がないため、ROPC フローを使用しないことをお勧めします。 ほとんどのシナリオでは、より安全な代替手段が利用でき、推奨されます。 このフローには、アプリケーションに対する高度な信頼が必要であり、他のフローに存在しないリスクが伴います。 このフローは、より安全なフローが実行できない場合にのみ使用します。 Microsoft は、悪意のある攻撃からユーザーを保護するために、この危険度の高い認証フローから離れています。 詳細については、「 Azure の必須多要素認証の計画」を参照してください。

ユーザーがサインイン時に存在する場合は、ActiveDirectoryInteractive 認証または ActiveDirectoryIntegrated 認証を使用して、サインインしているユーザーポリシーと条件付きアクセス ポリシーに監査証跡属性が適用されるようにします。

サービス間の無人シナリオの場合は、Microsoft Entra サービス アカウントのガイダンスに従ってください。

  • アプリケーションがAzureインフラストラクチャで実行されている場合は、ActiveDirectoryMSI (または一部のドライバーでは ActiveDirectoryManagedIdentity) を使用します。 マネージド ID により、シークレットと証明書の保守とローテーションのオーバーヘッドが排除されます。
  • マネージド ID が使用できない場合 (たとえば、アプリケーションはAzure外で実行されます)、ActiveDirectoryServicePrincipal を使用します。 ドライバーでサポートされている場合は、クライアント シークレットよりもクライアント証明書を優先します。 証明書を使用すると、秘密キーはクライアント上にとどまり、署名されたアサーションのみがクライアントを認証するためにMicrosoft Entraに送信されます。 キーがハードウェア (TPM や HSM など) に格納されている場合、または非エクスポートとしてマークされている場合、クライアント シークレットのように文字列としてコピーすることはできません。
  • Microsoft Entra ユーザー アカウントをサービス アカウントとして使用しないでください。

Microsoft Entraアカウントでユーザー名とパスワードが必要な場合はパスワード認証を使いましょう。 ユーザーは以下のデータベースアカウントを作成している必要があります CREATE USER [user@domain.com] FROM EXTERNAL PROVIDER:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryPassword;"
    "UID=<login@domain.com>;"
    "PWD=<password>;"
    "Encrypt=yes;"
)

Windows統合認証

Kerberosを用いたドメイン参加Windows環境にはWindows統合認証を使用してください。 このモードでは、オンプレミスの Active DirectoryがMicrosoft Entra IDと連携し、サーバー上でMicrosoft Entra管理者が設定されている必要があります:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryIntegrated;"
    "Encrypt=yes;"
)

このモードは現在のWindowsユーザーのKerberos認証情報を使用します。 LinuxとmacOSでは、Kerberosは手動で設定する必要があります(krb5.conf と有効なキータブまたはチケットが必要です)。 クライアント側のKerberos設定については、「SQL Server on LinuxでのActive Directory認証使用」を参照してください。

アクセス トークン認証

例えば、カスタムトークンプロバイダーや共有トークンキャッシュを通じて外部からトークンを取得することもできます。 この場合、SQL_COPT_SS_ACCESS_TOKENパラメータを持つattrs_beforeを使ってトークンを直接渡します。 この方法はドライバーの内蔵トークン取得フローをバイパスします。

import mssql_python
from azure.identity import DefaultAzureCredential
import struct

def get_token():
    credential = DefaultAzureCredential(
        exclude_interactive_browser_credential=False
    )
    token_bytes = credential.get_token(
        "https://database.windows.net/.default"
    ).token.encode("utf-16le")
    token_struct = struct.pack(
        f'<I{len(token_bytes)}s', len(token_bytes), token_bytes
    )
    return token_struct

SQL_COPT_SS_ACCESS_TOKEN = 1256

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;",
    attrs_before={SQL_COPT_SS_ACCESS_TOKEN: get_token()}
)

Important

SQL_COPT_SS_ACCESS_TOKENを使用する場合、接続文字列にはUIDPWDAuthenticationTrusted_Connectionが含まれてはなりません。 トークン自体が認証を担当します。

認証モードの選択

Scenario 推奨モード
開発マシン ActiveDirectoryDefault(Azure CLI を使用します)
Azure App Service / Functions ActiveDirectoryMSI (デフォルトより速い)
Azure Kubernetes Service ActiveDirectoryDefault (作業負荷の識別)
オンプレミスでの自動スクリプト ActiveDirectoryServicePrincipal
インタラクティブなデスクトップアプリ ActiveDirectoryInteractive
ブラウザなしのSSH/コンテナ ActiveDirectoryDeviceCode

Troubleshoot

"ユーザー 'NT AUTHORITY\ANONYMOUS LOGON' はログインできませんでした"

ユーザーまたは管理されたアイデンティティがデータベースに存在しているか確認します:

CREATE USER [identity-name] FROM EXTERNAL PROVIDER;

「AADSTS700016:申請が見つかりません」

サービスプリンシパルまたはアプリケーションIDが誤っています。 クライアントIDとアプリがMicrosoft Entraテナントに登録されているかを確認してください。

「マネージデンティド・アイデンティティのエンドポイントに到達できません」

  • AzureリソースでマネージドIDが有効になっているか確認してください。
  • ユーザー割り当てのIDについては、クライアントIDが正しいか確認してください。
  • リソースが識別エンドポイントへのネットワークアクセスを持っているか確認してください。

トークン取得タイムアウト

ActiveDirectoryDefaultDefaultAzureCredential を使用します。これは、認証情報プロバイダーのチェーンを順番にたどり、いずれかが成功するまで続行します。 このチェーンウォークは、特にチェーン内の前のプロバイダー(環境変数やワークロード識別)が動作するプロバイダーに到達する前に失敗した場合、最初の接続で数秒の遅延を生みます。 本番環境では、チェーンをスキップするために認証情報タイプを直接指定します:

# Slow: DefaultAzureCredential tries multiple providers
conn = mssql_python.connect(connection_string, authentication="ActiveDirectoryDefault")

# Fast: Skip directly to managed identity
conn = mssql_python.connect(connection_string, authentication="ActiveDirectoryMSI")