この記事では、mssql-django バックエンドを使用して Django アプリケーションのMicrosoft Entra認証を構成する方法について説明します。 Microsoft Entra認証を使用すると、アプリケーション構成にパスワードを格納する必要がなくなります。
前提条件
-
Microsoft ODBC Driver 18 for SQL Server(推奨)。 この記事のすべての認証モードは、Microsoft ODBC Driver 18 for SQL Serverでサポートされています。
ActiveDirectoryInteractiveは、ドライバーのバージョンに関係なくWindows専用です。 ODBC Driver 17 を使用する必要がある場合は、モードごとの最小 17.x バージョンの ODBC 認証リファレンス を参照してください。 - アクセス トークン認証の場合:
pip install azure-identity。
認証方法
Django プロジェクトのDATABASES ファイルでsettings.py設定を追加または編集して、各メソッドを構成します。 この記事の例では、明確にするために完全な DATABASES["default"] ブロックを示します。関連するキーを既存の構成にコピーします。
mssql-djangoでは、次の 2 つの方法でMicrosoft Entra認証がサポートされます。
-
OPTIONS["extra_params"]による ODBC ドライバー認証。 バックエンドは、この文字列を変更せずに ODBC 接続文字列に追加するため、使用可能なAuthentication=の値は、mssql-django自体からではなく、インストールされている Microsoft ODBC Driver for SQL Serverから取得されます。 -
TOKEN設定を使用したプログラムによるアクセス トークン認証。 バックエンドは、ODBCTOKENキーワードをバイパスするSQL_COPT_SS_ACCESS_TOKENとして、Authentication=を ODBC ドライバーに渡します。
認証方法の概要
| Method | を使用して構成する | 最適な用途 |
|---|---|---|
| アクセス トークン | TOKEN |
開発、有効期間の短いスクリプト、またはカスタム トークン更新を使用するアプリ |
ActiveDirectoryMsi |
extra_params |
Azureホスト型運用アプリ (システム割り当てマネージド ID とユーザー割り当てマネージド ID) |
ActiveDirectoryServicePrincipal |
USER、PASSWORD、extra_params |
マネージド ID を利用できない場合のアプリの登録 |
ActiveDirectoryIntegrated |
extra_params |
ドメイン参加済みユーザー コンテキスト |
ActiveDirectoryInteractive |
USER、extra_params |
多要素認証を使用したユーザー サインイン (Windows) |
ActiveDirectoryDefault |
extra_params |
ODBC ドライバーの既定の Microsoft Entra 資格情報チェーンを使用すべきローカル開発環境およびアプリ |
ActiveDirectoryPassword |
USER、PASSWORD、extra_params |
最終手段のレガシー シナリオ専用 (非推奨) |
Note
mssql-django 1.7.3 以降では、インストールされている Microsoft ODBC Driver for SQL Server がそのモードをサポートしている場合、Authentication=ActiveDirectoryDefault から OPTIONS["extra_params"] までを受け入れます。 トークンの取得と更新の動作を明示的に制御する必要がある場合は、 クラスで azure.identity.DefaultAzureCredential パターンを使用します。
Azure SQLで ID アクセス権を付与する
マネージド ID またはサービス プリンシパル認証の場合は、データベース ユーザーを作成し、アプリケーションに必要なロールのみを付与します。
CREATE USER [<identity-name>] FOR EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
ALTER ROLE db_ddladmin ADD MEMBER [<identity-name>];
db_ddladmin固定データベース ロールは、アプリケーションが移行を実行する場合にのみ必要です。 読み取り専用ワークロードの場合は、 db_datareader で十分です。
Note
FROM EXTERNAL PROVIDERでは、SQL サーバーがプリンシパル名を解決するためにMicrosoft Graphを呼び出す必要があります。 サーバーがMicrosoft Entra専用認証用に構成されている場合、または Graph に到達できない場合、ステートメントは Msg 33130 (Principal '<name>' could not be found...) で失敗します。 明示的な SID を指定して、ユーザーを手動で作成します。
CREATE USER [<identity-name>] WITH SID = 0x<sid-hex>, TYPE = E;
マネージド ID またはサービス プリンシパルの場合は、オブジェクト ID ではなく、ID の アプリケーション (クライアント) ID から SID を派生させます。 Azure SQLは、サービス プリンシパルとマネージド ID にアプリケーション ID を使用し、オブジェクト ID は通常の Entra ユーザーにのみ使用します。 ダッシュ区切りの最初の 3 つのグループをバイト単位で反転し、最後の 2 つはそのままにして GUID を変換します。 たとえば、アプリケーション ID 619a4449-b4aa-4383-a2a9-7c365106c5e7 は SID 0x49449A61AAB48343A2A97C365106C5E7になります。 PowerShell では次のとおりです。
$b = ([Guid]"<app-id>").ToByteArray()
"0x" + (($b | ForEach-Object { $_.ToString('X2') }) -join '')
オブジェクト ID を誤って使用すると、接続はトークンの取得に成功しますが、Azure SQLはトークンのLogin failed for user '<token-identified principal>'要求と一致するデータベース プリンシパルがないため、appidを返します。
VIEW ANY COLUMN MASTER KEY DEFINITION permission denied エラーが表示された場合は、Always Encrypted シナリオに対して ID に追加のアクセス権を付与します。
GRANT VIEW ANY COLUMN MASTER KEY DEFINITION TO [<identity-name>];
GRANT VIEW ANY COLUMN ENCRYPTION KEY DEFINITION TO [<identity-name>];
マネージド ID 認証 (ActiveDirectoryMsi)
Django アプリがAzure App Service、Azure Container Apps、Azure 仮想マシンなどのAzure サービスで実行されている場合は、マネージド ID を使用します。 ODBC ドライバーはトークンを自動的に取得して更新するため、運用環境ではこの方法をお勧めします。
システムによって割り当てられたマネージド ID
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryMsi",
},
},
}
ユーザー割り当て管理対象 ID
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": (
"Authentication=ActiveDirectoryMsi;"
"UID=<managed-identity-client-id-or-object-id>"
),
},
},
}
ActiveDirectoryMsi は、システム割り当てマネージド ID (SAMI) とユーザー割り当てマネージド ID (UAMI) の両方の ODBC モードです。 UAMI の場合、ODBC ドライバーでは、UIDがマネージド ID を識別することを想定しています。Azure App Serviceまたは Azure Container Instance の場合はクライアント ID を使用し、それ以外の場合はオブジェクト ID を使用します。
UIDは ODBC ドライバーに直接渡されるため、extra_params内にそのextra_paramsを配置します。
マネージド ID を使用する場合は、テスト データベースを手動で作成し、単体テストを実行する際に --keepdb を渡してください。
サービス プリンシパル認証 (ActiveDirectoryServicePrincipal)
ユーザー コンテキストなしでアプリが実行され、マネージド ID が使用できない場合は、Microsoft Entra アプリ登録 (サービス プリンシパル) を使用します。
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"USER": "<application-client-id>",
"PASSWORD": "<client-secret>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryServicePrincipal",
},
},
}
settings.pyでクライアント シークレットをハードコーディングしないでください。 Azure Key Vaultなどの環境変数またはシークレット マネージャーを使用して、実行時に資格情報を指定します。
統合認証 (ActiveDirectoryIntegrated)
ドメインに参加しているユーザー コンテキストで Django プロセスが実行され、ODBC ドライバーがそのWindowsまたは Kerberos ID をMicrosoft Entra認証に使用する場合は、統合認証を使用します。
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryIntegrated",
},
},
}
ODBC 認証リファレンスでは、Windows、および Linux または macOS と ODBC Driver 17.6 以降のバージョンのフェデレーション環境でのこのモードについて説明します。
対話型認証 (ActiveDirectoryInteractive)
ドライバーで資格情報の入力を求め、多要素認証を処理する場合は、ローカル ユーザーサインインに対話型認証を使用します。
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"USER": "<user@email.com>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryInteractive",
},
},
}
主要な ODBC 認証のリファレンス ドキュメントでは、ActiveDirectoryInteractive を Windows 専用としています。 別のプラットフォームで使用する場合は、最初に正確なドライバー バージョンで動作を検証します。
既定の資格情報チェーンによる認証 (ActiveDirectoryDefault)
ODBC ドライバーで既定のMicrosoft Entra資格情報チェーンを適用する場合は、このモードを使用します。
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryDefault",
},
},
}
mssql-django 1.7.3 以降のバージョンでは、このモードが ODBC ドライバーに渡されます。 資格情報ソースまたはトークン更新の動作を明示的に制御する必要がある場合は、 アクセス トークン認証を使用します。
アクセス トークン認証 (TOKEN)
Python コードでMicrosoft Entra トークン自体を取得する場合は、TOKENを使用します。
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
token = credential.get_token("https://database.windows.net/.default").token
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"TOKEN": token,
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
},
},
}
このパスは、DefaultAzureCredential、ManagedIdentityCredential、ClientSecretCredentialなど、任意のPython資格情報クラスで動作します。
settings.pyでフェッチされたアクセス トークンは、プロセスの起動時に 1 回評価され、通常は 60 分から 90 分後に期限切れになります。 Django プロセスがトークンの有効期間より長く存続する場合は、アプリケーション コードでトークンを更新する必要があります。 実行時間の長いほとんどの運用アプリでは、 ActiveDirectoryMsi や ActiveDirectoryServicePrincipalなど、トークンを自動的に更新する ODBC ドライバー モードを使用します。
パスワード認証 (ActiveDirectoryPassword、非推奨)
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 ユーザー アカウントをサービス アカウントとして使用しないでください。
レガシ シナリオで使用する必要がある場合は、明示的に構成します。
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": "<your-database>",
"USER": "<user@email.com>",
"PASSWORD": "<your-password>",
"HOST": "<your-server>.database.windows.net",
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryPassword",
},
},
}