この記事では、従来の認証方法から、Azure Database for MySQL を使用したより安全なパスワードレス接続に移行する方法について説明します。
Azure Database for MySQL へのアプリケーション要求を認証する必要があります。 Azure Database for MySQL には、アプリが安全に接続するためのさまざまな方法が用意されています。 パスワードを使用する方法の 1 つ。 ただし、可能な場合は、アプリケーションのパスワードレス接続に優先順位を付ける必要があります。
認証オプションを比較する
アプリケーションが Azure Database for MySQL で認証されると、データベースに接続するためのユーザー名とパスワードのペアが提供されます。 ID の格納場所に応じて、Microsoft Entra 認証と MySQL 認証の 2 種類の認証があります。
Microsoft Entra 認証
Microsoft Entra 認証は、Microsoft Entra ID で定義されている ID を使用して Azure Database for MySQL に接続するためのメカニズムです。 Microsoft Entra認証を使用すると、データベース ユーザー ID やその他のMicrosoft サービスを一元的な場所で管理できるため、アクセス許可の管理が簡略化されます。
認証に Microsoft Entra ID を使用すると、次の利点があります。
- 一様な方法で Azure Services 全体のユーザーを認証します。
- 1 か所でのパスワード ポリシーとパスワード ローテーションの管理。
- Microsoft Entra ID でサポートされる複数の形式の認証により、パスワードを格納する必要がなくなります。
- お客様は、外部 (Microsoft Entra ID) グループを使用してデータベースのアクセス許可を管理できます。
- Microsoft Entra 認証では、MySQL データベース ユーザーを使用して、データベース レベルで ID を認証します。
- Azure Database for MySQL に接続するアプリケーションに対するトークンベースの認証のサポート。
MySQL 認証
MySQL でアカウントを作成できます。 アカウントの資格情報としてパスワードを使用する場合は、 user テーブルにこれらの資格情報が格納されます。 MySQL にはこれらのパスワードが格納されるため、パスワードのローテーションを自分で管理する必要があります。
パスワードを使用してAzure Database for MySQLに接続することはできますが、慎重に使用してください。 安全でない場所でパスワードを公開しないでください。 パスワードにアクセスできるユーザーは誰でも認証できます。 たとえば、悪意のあるユーザーは、ソース管理に接続文字列を誤ってチェックインしたり、安全でないメールで送信したり、間違ったチャットに貼り付けたり、アクセス許可のないユーザーがアプリケーションを表示したりする場合に、アプリケーションにアクセスする可能性があります。 代わりに、パスワードレス接続を使用するようにアプリケーションを更新することを検討してください。
パスワードレス接続の概要
パスワードなしの接続を使用すると、アプリケーション コード、その構成ファイル、または環境変数に資格情報を格納することなく、Azure サービスに接続できます。
多くの Azure サービスでは、たとえば Azure マネージド ID を使用したパスワードレス接続がサポートされています。 これらの手法により、Azure Identity クライアント ライブラリから DefaultAzureCredential を使用して実装できる堅牢なセキュリティ機能が提供されます。 このチュートリアルでは、接続文字列などの代替手段ではなく、 DefaultAzureCredential を使用するように既存のアプリケーションを更新する方法について説明します。
DefaultAzureCredential では、複数の認証方法がサポートされ、実行時に使用する必要がある認証方法が自動的に決定されます。 この方法を使用すると、環境固有のコードを実装することなく、アプリで異なる環境 (ローカル開発と運用) で異なる認証方法を使用できます。
DefaultAzureCredentialが資格情報を検索する順序と場所については、Azure ID ライブラリの概要を参照してください。 たとえば、ローカルで作業する場合、 DefaultAzureCredential は通常、開発者が Visual Studio へのサインインに使用したアカウントを使用して認証されます。 アプリが Azure にデプロイされると、 DefaultAzureCredential はマネージド ID を使用するように自動的に切り替わります。 この切り替えにコードを変更する必要はありません。
接続がパスワードレスであることを確認するには、ローカル開発と運用環境の両方を考慮する必要があります。 いずれかの場所で接続文字列が必要な場合、アプリケーションはパスワードレスではありません。
ローカル開発環境では、Visual Studio Code または IntelliJ 用の Azure CLI、Azure PowerShell、Visual Studio、または Azure プラグインを使用して認証できます。 この場合、プロパティを構成する代わりに、アプリケーションでその資格情報を使用できます。
仮想マシンなどの Azure ホスティング環境にアプリケーションをデプロイする場合は、その環境でマネージド ID を割り当てることができます。 その後、Azure サービスに接続するために資格情報を指定する必要はありません。
注
マネージド ID は、アプリまたはサービスを表すセキュリティ ID を提供します。 ID は Azure プラットフォームによって管理され、シークレットをプロビジョニングまたはローテーションする必要はありません。 マネージド ID の詳細については、 概要 ドキュメントを参照してください。
パスワードレス接続を使用するように既存のアプリケーションを移行する
次の手順では、パスワードベースのソリューションではなく、パスワードレス接続を使用するように既存のアプリケーションを移行する方法について説明します。
0) 作業環境の準備
まず、次のコマンドを使用して、いくつかの環境変数を設定します。
export AZ_RESOURCE_GROUP=<YOUR_RESOURCE_GROUP>
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=demo
export AZ_MYSQL_AD_NON_ADMIN_USERNAME=<YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>
export AZ_MYSQL_AD_MI_USERNAME=<YOUR_AZURE_AD_MI_DISPLAY_NAME>
export AZ_USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName --output tsv)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id --output tsv)
プレースホルダーを次の値に置き換えます。この値は、この記事全体で使用されます。
-
<YOUR_RESOURCE_GROUP>: お使いのリソースのリソース グループの名前。 -
<YOUR_DATABASE_SERVER_NAME>: MySQL サーバーの名前。Azure 全体で一意である必要があります。 -
<YOUR_AZURE_AD_NON_ADMIN_USER_DISPLAY_NAME>: Microsoft Entra の管理者以外のユーザーの表示名。 名前がMicrosoft Entra テナントの有効なユーザーであることを確認します。 -
<YOUR_AZURE_AD_MI_DISPLAY_NAME>: マネージド ID の Microsoft Entra ユーザーの表示名。 名前がMicrosoft Entra テナントの有効なユーザーであることを確認します。 -
<YOUR_USER_ASSIGNED_MANAGEMED_IDENTITY_NAME>: ユーザー割り当てマネージド ID サーバーの名前。Azure 全体で一意である必要があります。
1) Azure Database for MySQL を構成する
1.1) Microsoft Entra ID ベースの認証を有効にする
Azure Database for MySQLでMicrosoft Entra IDアクセスを使用するには、最初にMicrosoft Entra管理者ユーザーを設定します。 Microsoft Entra ID ベースの認証に対してユーザーを作成または有効にできるのは、Microsoft Entra管理者ユーザーだけです。
Azure CLIを使用している場合は、次のコマンドを実行して、十分なアクセス許可があることを確認します。
az login --scope https://graph.microsoft.com/.default
次のコマンドを実行して、割り当て用のユーザー ID を作成します。
az identity create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_USER_IDENTITY_NAME
Important
ユーザー割り当て ID を作成した後、 グローバル管理者 または 特権ロール管理者 に、この ID に対して次のアクセス許可を付与するように依頼します: User.Read.All、 GroupMember.Read.All、および Application.Read.ALL。 詳細については、「Active Directory 認証のアクセス許可」セクションを参照してください。
次のコマンドを実行して、Microsoft Entra 管理者を作成するための ID を MySQL サーバーに割り当てます。
az mysql flexible-server identity assign \
--resource-group $AZ_RESOURCE_GROUP \
--server-name $AZ_DATABASE_SERVER_NAME \
--identity $AZ_USER_IDENTITY_NAME
次に、次のコマンドを実行して、Microsoft Entra管理者を設定します。
az mysql flexible-server ad-admin create \
--resource-group $AZ_RESOURCE_GROUP \
--server-name $AZ_DATABASE_SERVER_NAME \
--display-name $CURRENT_USERNAME \
--object-id $CURRENT_USER_OBJECTID \
--identity $AZ_USER_IDENTITY_NAME
このコマンドは、Microsoft Entra管理者を現在サインインしているユーザーに設定します。
注
MySQL サーバーごとに作成できる Microsoft Entra 管理者は 1 つだけです。 別の管理者を選択すると、サーバー用に構成された既存のMicrosoft Entra管理者が上書きされます。
2) ローカル開発用に Azure Database for MySQL を構成する
2.1) ローカル IP のファイアウォール規則を構成する
Azure Database for MySQL インスタンスは、既定でセキュリティで保護されています。 受信接続を許可しないファイアウォールがあります。
flexible-server create コマンドによってローカル IP アドレスが既に検出され、MySQL サーバーに設定されているため、Bash を使用している場合は、この手順をスキップできます。
Windows コンピューター上の Linux 用 Windows サブシステム (WSL) から MySQL サーバーに接続する場合は、WSL ホスト ID をファイアウォールに追加する必要があります。 WSL で次のコマンドを実行して、ホスト コンピューターの IP アドレスを取得します。
cat /etc/resolv.conf
nameserverという用語の後に IP アドレスをコピーし、次のコマンドを使用して WSL IP アドレスの環境変数を設定します。
export AZ_WSL_IP_ADDRESS=<the-copied-IP-address>
次に、次のコマンドを使用して、WSL ベースのアプリに対するサーバーのファイアウォールを開きます。
az mysql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_SERVER_NAME-database-allow-local-ip-wsl \
--server $AZ_DATABASE_SERVER_NAME \
--start-ip-address $AZ_WSL_IP_ADDRESS \
--end-ip-address $AZ_WSL_IP_ADDRESS \
--output tsv
2.2) MySQL の管理者以外のユーザーを作成し、アクセス許可を付与する
次に、管理者以外の Microsoft Entra ユーザーを作成し、 $AZ_DATABASE_NAME データベースに対するすべてのアクセス許可を付与します。 ニーズに合わせてデータベース名 $AZ_DATABASE_NAME を変更できます。
管理者以外のユーザーを作成するための create_ad_user.sql という名前の SQL スクリプトを作成します。 次の内容を追加し、ローカルに保存します。
export AZ_MYSQL_AD_NON_ADMIN_USERID=$(az ad signed-in-user show --query id --output tsv)
cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER '$AZ_MYSQL_AD_NON_ADMIN_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_NON_ADMIN_USERID';
GRANT ALL PRIVILEGES ON $AZ_DATABASE_NAME.* TO '$AZ_MYSQL_AD_NON_ADMIN_USERNAME'@'%';
FLUSH privileges;
EOF
次に、次のコマンドを使用して SQL スクリプトを実行し、管理者以外のユーザー Microsoft Entra作成します。
mysql -h $AZ_DATABASE_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql
次に、次のコマンドを使用して、一時 SQL スクリプト ファイルを削除します。
rm create_ad_user.sql
注
MySQL ユーザーの作成の詳細については、「Azure Database for MySQL でのユーザーの作成」を参照してください。
3) サインインしてアプリ コードを移行してパスワードレス接続を使用する
ローカル開発の場合は、MySQL でロールを割り当てたのと同じMicrosoft Entra アカウントで認証されていることを確認します。 Azure CLI、Visual Studio、Azure PowerShell、または IntelliJ などの他のツールを使用して認証します。
次のコマンドを使用して、Azure CLI を使用して Azure にサインインします。
az login
次に、次の手順を使用して、パスワードなしの接続を使用するようにコードを更新します。 概念的には似ていますが、各言語では異なる実装の詳細が使用されます。
プロジェクト内で、次の参照を
azure-identity-extensionsパッケージに追加します。 このライブラリには、パスワードレス接続を実装するために必要なすべてのエンティティが含まれています。<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity-extensions</artifactId> <version>1.0.0</version> </dependency>JDBC URL で Azure MySQL 認証プラグインを有効にします。 現在、Azure Database for MySQL に接続するための
java.sql.Connectionを作成しているコード内の場所を特定します。 application.properties ファイル内のurlとuserを、次の値に合わせて更新します。url=jdbc:mysql://$AZ_DATABASE_SERVER_NAME.mysql.database.azure.com:3306/$AZ_DATABASE_NAME?serverTimezone=UTC&sslMode=REQUIRED&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin user=$AZ_MYSQL_AD_NON_ADMIN_USERNAME注
MysqlConnectionPoolDataSourceクラスをアプリケーションのデータソースとして使用している場合は、URL からdefaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPluginを削除します。url=jdbc:mysql://$AZ_DATABASE_SERVER_NAME.mysql.database.azure.com:3306/$AZ_DATABASE_NAME?serverTimezone=UTC&sslMode=REQUIRED&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin user=$AZ_MYSQL_AD_NON_ADMIN_USERNAME$AZ_DATABASE_SERVER_NAME、$AZ_DATABASE_NAME、および$AZ_MYSQL_AD_NON_ADMIN_USERNAME変数を、この記事の冒頭で構成した値に置き換えます。JDBC URL から
passwordを削除します。
アプリをローカルで実行する
これらのコードを変更した後、アプリケーションをローカルで実行します。 互換性のある IDE またはコマンド ライン ツール (Azure CLI、Visual Studio、IntelliJ など) にサインインしている場合、新しい構成によってローカル資格情報が選択されます。 Azureでローカル開発ユーザーに割り当てたロールにより、アプリはAzure サービスにローカルで接続できます。
4) Azure ホスティング環境を構成する
パスワードレス接続を使用するようにアプリケーションを構成し、ローカルで実行した後、Azureにデプロイした後、同じコードをAzure サービスに対して認証できます。 たとえば、マネージド ID が割り当てられている Azure App Service インスタンスにデプロイされたアプリケーションは、Azure Storage に接続できます。
このセクションでは、2 つの手順を実行して、パスワードなしの方法でアプリケーションを Azure ホスティング環境で実行できるようにします。
- Azure ホスティング環境のマネージド ID を割り当てます。
- マネージド ID にロールを割り当てます。
注
Azure には Service Connector も用意されています。これは、ホスティング サービスを PostgreSQL に接続するのに役立ちます。 Service Connector を使用してホスティング環境を構成すると、Service Connector によって割り当てられるため、マネージド ID にロールを割り当てる手順を省略できます。 次のセクションでは、2 つの方法で Azure ホスティング環境を構成する方法について説明します。1 つは Service Connector 経由で、もう 1 つは各ホスティング環境を直接構成することです。
Important
Service Connector のコマンドには 、Azure CLI 2.41.0 以降が必要です。
Azure portal を使用してマネージド ID を割り当てる
次の手順では、さまざまな Web ホスティング サービスにシステム割り当てマネージド ID を割り当てる方法を示します。 マネージド ID は、前に設定したアプリ構成を使用して、他のAzure サービスに安全に接続できます。
Azure App Service インスタンスのメイン概要ページで、ナビゲーション ウィンドウから [ID] を選択します。
[ システム割り当て済み ] タブで、[ ステータス] フィールドを オンに設定します。 システム割り当て ID は Azure によって内部的に管理され、管理タスクが自動的に処理されます。 identity の詳細や ID がコード内に公開されることはありません。
Azure CLIを使用して、Azure ホスティング環境でマネージド ID を割り当てることもできます。
次の例に示すように、 az webapp identity assign コマンドを使用して、マネージド ID を Azure App Service インスタンスに割り当てることができます。
export AZ_MI_OBJECT_ID=$(az webapp identity assign \
--resource-group $AZ_RESOURCE_GROUP \
--name <service-instance-name> \
--query principalId \
--output tsv)
マネージド ID にロールを割り当てる
次に、MySQL インスタンスにアクセスするために割り当てたマネージド ID にアクセス許可を付与します。
次の手順では、マネージド ID のMicrosoft Entra ユーザーを作成し、それにデータベース $AZ_DATABASE_NAMEのすべてのアクセス許可を付与します。 ニーズに合わせてデータベース名 $AZ_DATABASE_NAME を変更できます。
まず、管理者以外のユーザーを作成するための create_ad_user.sql という名前の SQL スクリプトを作成します。 次の内容を追加し、ローカルに保存します。
export AZ_MYSQL_AD_MI_USERID=$(az ad sp show --id $AZ_MI_OBJECT_ID --query appId --output tsv)
cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;
CREATE AADUSER '$AZ_MYSQL_AD_MI_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_MI_USERID';
GRANT ALL PRIVILEGES ON $AZ_DATABASE_NAME.* TO '$AZ_MYSQL_AD_MI_USERNAME'@'%';
FLUSH privileges;
EOF
次に、次のコマンドを使用して SQL スクリプトを実行し、管理者以外のユーザー Microsoft Entra作成します。
mysql -h $AZ_DATABASE_SERVER_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql
次に、次のコマンドを使用して、一時 SQL スクリプト ファイルを削除します。
rm create_ad_user.sql
アプリをテストする
アプリをホスティング環境にデプロイする前に、マネージド ID 用に作成したユーザーを使用してアプリケーションが MySQL に接続するため、コードをもう 1 つ変更する必要があります。
これらのコードを変更した後、アプリケーションをビルドして再デプロイできます。 次に、ブラウザーでホストされているアプリケーションを参照します。 アプリは MySQL データベースに正常に接続できる必要があります。 ロールの割り当てがAzure環境に反映されるまでに数分かかる場合があります。 アプリケーションがローカル環境と運用環境の両方で実行されるように構成され、開発者はアプリケーション自体でシークレットを管理する必要がありません。
次のステップ
このチュートリアルでは、アプリケーションをパスワードレス接続に移行する方法について説明しました。
この記事で説明する概念の詳細については、次のリソースを参照してください。