サービス プリンシパルを使用したローカル開発時に Azure サービスに対して JavaScript アプリを認証する
クラウド アプリケーションを作成する場合、開発者はローカル ワークステーションでアプリケーションをデバッグおよびテストする必要があります。 ローカル開発時に開発者のワークステーションでアプリケーションを実行する場合でも、アプリで使用されるすべての Azure サービスに対して認証する必要があります。 この記事では、ローカル開発時に使用する専用のアプリケーション サービス プリンシパル オブジェクトを設定する方法について説明します。
ローカル開発用の専用アプリケーション サービス プリンシパルを使用すると、アプリ開発時に最小限の特権の原則に従うことができます。 アクセス許可のスコープは開発時にアプリに必要なものだけに設定されるため、別のアプリで使用することを目的とした Azure リソースにアプリ コードが誤ってアクセスすることはありません。 また、この方法では、開発環境でアプリが過剰な特権を持っていたために、アプリが運用環境に移動されたときにバグが発生するのを防ぐことができます。
アプリが Azure に登録されると、アプリケーション サービス プリンシパルがアプリ用に設定されます。 ローカル開発用にアプリを登録する場合は、次の手順を実行することをお勧めします。
- アプリで作業する開発者ごとに個別のアプリ登録を作成します。 この方法では、ローカル開発時に使用する各開発者に対して個別のアプリケーション サービス プリンシパルが作成され、開発者が 1 つのアプリケーション サービス プリンシパルの資格情報を共有する必要がなくなります。
- アプリごとに個別のアプリ登録を作成します。 これにより、アプリのアクセス許可のスコープがアプリに必要なものだけに設定されます。
ローカル開発時に、環境変数はアプリケーション サービス プリンシパルの ID で設定されます。 Azure SDK for JavaScript では、これらの環境変数を読み取り、この情報を使用して、必要な Azure リソースに対してアプリが認証されます。
1 - Azure にアプリケーションを登録する
アプリケーション サービス プリンシパル オブジェクトは、Azure でアプリの登録を使用して作成されます。 サービス プリンシパルは、Azure portal または Azure CLI を使用して作成できます。
Azure portal にサインインして、次の手順を実行します。
2 - ローカル開発用の Microsoft Entra セキュリティ グループを作成する
通常、アプリケーションで作業する開発者は複数いるため、個々のサービス プリンシパル オブジェクトにロールを割り当てるのではなく、Microsoft Entra グループを作成して、アプリがローカル開発で必要とするロール (アクセス許可) をカプセル化することをお勧めします。 これには次のような利点があります。
- ロールはグループ レベルで割り当てられるため、すべての開発者に同じロールが割り当てられることが保証されます。
- アプリに新しいロールが必要な場合は、アプリの Microsoft Entra グループに追加するだけで済みます。
- 新しい開発者がチームに参加する場合は、アプリで作業するための適切なアクセス許可が開発者に与えられるように、その開発者用に新しいアプリケーション サービス プリンシパルを作成してグループに追加します。
3 - アプリケーションにロールを割り当てる
次に、アプリで必要なリソースに対して必要なロール (アクセス許可) を決定し、それらのロールをアプリに割り当てる必要があります。 この例では、手順 2 で作成した Microsoft Entra グループにロールが割り当てられます。 ロールは、リソース、リソース グループ、またはサブスクリプション スコープで割り当てることができます。 次に、ほとんどのアプリケーションがすべてのAzureリソースを1つのリソースグループにグループ化するため、リソースグループスコープでロールを割り当てる例を示します。
4 - ローカル開発の環境変数を設定する
DefaultAzureCredential
オブジェクトは、一連の環境変数ランタイムでサービス プリンシパル情報を検索します。 ほとんどの開発者は複数のアプリケーションで作業するため、dotenv などのパッケージを使用して、開発時にアプリケーションのディレクトリに格納されている .env
ファイルから環境にアクセスすることをお勧めします。 このようにすると、Azure に対してアプリケーションを認証するために使用される環境変数のスコープが設定され、このアプリケーションのみで使用できます。
.env
ファイルには Azure のアプリケーション シークレット キーが含まれているので、ソース管理にチェックインされることはありません。 JavaScript 用の標準の .gitignore ファイルでは、チェックインから .env
ファイルが自動的に除外されます。
dotenv
パッケージを使用するには、まずアプリケーションにパッケージをインストールします。
npm install dotenv
次に、アプリケーションのルート ディレクトリに .env
ファイルを作成します。 次のように、アプリ登録プロセスから取得した値を使用して環境変数の値を設定します。
AZURE_CLIENT_ID
→ アプリ ID の値です。AZURE_TENANT_ID
→ テナント ID の値です。AZURE_CLIENT_SECRET
→アプリ用に生成されたパスワード/資格情報。
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=ffffaaaa-5555-bbbb-6666-cccc7777dddd
AZURE_CLIENT_SECRET=Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2
最後に、アプリケーションのスタートアップ コードで、dotenv
ライブラリを使用して、起動時に .env
ファイルから環境変数を読み取ります。
import 'dotenv/config'
5 - アプリケーションに DefaultAzureCredential を実装する
Azure SDK クライアント オブジェクトを Azure に対して認証するには、アプリケーションで DefaultAzureCredential
パッケージから @azure/identity
クラスを使用する必要があります。 このシナリオでは、DefaultAzureCredential
が環境変数AZURE_CLIENT_ID
、AZURE_TENANT_ID
を検出し、AZURE_CLIENT_SECRET
が設定され、これら変数を読み取り Azure に接続するためのアプリケーション サービス プリンシパル情報を取得します。
まず、@azure/identity パッケージを アプリケーションに追加します。
npm install @azure/identity
次に、アプリで Azure SDK クライアント オブジェクトを作成する JavaScript コードの場合、次のことが必要になります。
DefaultAzureCredential
モジュールから@azure/identity
クラスをインポートします。DefaultAzureCredential
オブジェクトを作成します。- Azure SDK クライアント オブジェクト コンストラクターに
DefaultAzureCredential
オブジェクトを渡します。
この例を次のコード セグメントに示します。
// Azure authentication dependency
import { DefaultAzureCredential } from '@azure/identity';
// Azure resource management dependency
import { SubscriptionClient } from "@azure/arm-subscriptions";
// Acquire credential
const tokenCredential = new DefaultAzureCredential();
async function listSubscriptions() {
try {
// use credential to authenticate with Azure SDKs
const client = new SubscriptionClient(tokenCredential);
// get details of each subscription
for await (const item of client.subscriptions.list()) {
const subscriptionDetails = await client.subscriptions.get(
item.subscriptionId
);
/*
Each item looks like:
{
id: '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e',
subscriptionId: 'aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e',
displayName: 'YOUR-SUBSCRIPTION-NAME',
state: 'Enabled',
subscriptionPolicies: {
locationPlacementId: 'Internal_2014-09-01',
quotaId: 'Internal_2014-09-01',
spendingLimit: 'Off'
},
authorizationSource: 'RoleBased'
},
*/
console.log(subscriptionDetails);
}
} catch (err) {
console.error(JSON.stringify(err));
}
}
listSubscriptions()
.then(() => {
console.log("done");
})
.catch((ex) => {
console.log(ex);
});
DefaultAzureCredential
では、アプリ用に構成された認証メカニズムを自動的に検出し、Azure に対してアプリを認証するために必要なトークンを取得します。 アプリケーションで複数の SDK クライアントを使用する場合は、各 SDK クライアント オブジェクトで同じ資格情報オブジェクトを使用できます。