By Daniel Laufenberg on 08/05/2024
Microsoft Entra ID(以前の名前はAzure Active Directory)はIT業界で最も人気のあるIDaaS(Identity as a Service)製品の1つです。Entra IDを使ったことがない人でも、以下のページを一度は見たことがあるかもしれません。
Microsoft Entra IDは、ユーザーのアイデンティティを管理し、企業のリソースを保護するために必要なすべてのツールを提供するクラウドベースのアイデンティティおよびアクセス管理サービスです。社内アプリにアクセスする前に表示されるこのログイン画面は、Entra IDがユーザーにアプリのアクセス権利があるかを確認していることを示しています。詳しい情報はMicrosoftの公式ドキュメントをご覧ください。
Microsoft Entra IDは単にアプリケーションの前に立つ「門番」見たいな物と思う方もいるでしょう。その考えは、一図として間違ってはありませんが、Microsoft Entra IDの機能性はそれにとどまりません。Entra IDは最前線のセキュリティとしてだけでなく、アプリケーションと直接統合し、各機能に対して細かなアクセス制御をする事も可能なんです。
今回はその作法をお見せしたいと思います。
当デモではRazor Pagesを使用し、各ページにて、ユーザー所有のアクセス権に応じて異なる機能を提供するウェブアプリケーションを作成します。アプリケーションのコードを書く前に、使用するEntra IDテナント内でアプリケーション登録を作成する必要があります。
サービスプリンシパルは、アプリケーションのセキュリティポリシーを担う認証エンティティです。Entra IDテナント内のリソースに対して、サービスプリンシパルに特定のアクセス権限を割り当てることができます。サービスプリンシパルはアクセスポリシーを人間のユーザーではなく、アプリケーションに適用させると考えるとわかりやすいでしょう。
これは、テナント内でグローバルなアプリケーションインスタンスを作成するプロセスを指しています。新しいアプリケーションインスタンスを作成する際に、そのアプリケーションインスタンスに付属されるサービスプリンシパルが同時に作成されます。
「すでにサービスプリンシパルがあるのに、なぜアプリケーション登録が必要なのか?」と疑問に思う方も多いでしょう。アプリケーション登録は関連するテナント間で共有されますが、サービスプリンシパルは各テナントに個別に作成されます。つまり、マルチテナント環境でアプリケーションが作成された場合、各テナントごとに独自のサービスプリンシパルが必要となるのです。
当デモでは寿司屋のウェブアプリケーションを作成します
ホーム (Home):すべてのユーザーが利用可能
キッチン (Kitchen):従業員のみ利用可能(Entraテナントのユーザー)
在庫ルーム (StockRoom):ヘッドシェフのみ利用可能。
必要な開発ツール
Azure CLI
Dotnet CLI
テキストエディター(このデモではVisual Studio Codeを使用しましたが、お好きなエディターで大丈夫です)
1. CLIでAzureにログイン
az login
2.アプリケーションの作成
#寿司レストランのアプリケーションを作成
az ad app create --display-name "sushi-restaurant"
#作成されたアプリケーションApp Idを取得
az ad app list --display-name "sushi-restaurant" --query "[0].appId" -o tsv
#アプリケーションの応答 URLの設定とトーケン発行を有効化
az ad app update --id {先ほどのappId} --web-redirect-uris=index
--enable-id-token-issuance
#設定変更が反映されたかを確認
az ad app list --display-name "sushi-restaurant" --query "[0].appId" -o tsv
#アプリケーションのパスワードを作成。パスワードは安全な場所に保管してください
az ad app credential reset --id {先ほどのappId} --append --query password
ウェブアプリケーションのコードは下記のリンクからダウンロードしてください。
ほとんどのコードはMicrosoftの公式ドキュメントを参考にしています。 https://learn.microsoft.com/en-us/entra/identity-platform/scenario-web-app-sign-user-app-configuration?tabs=aspnetcore
1. コードをエディターで開き 「appSetting.json」を下記のように設定する
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "{テナントID}",
"ClientId": "{アプリケーションのappId}",
"CallbackPath": "/index",
"ClientSecret": "先ほど作成したパスワード"
},
"AllowedHosts": "*"
}
2. 「program.cs」に下記のコードを加える。これによりMicrosoft Entra IDが認証に使われます。
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd");
builder.Services.AddRazorPages()
.AddMvcOptions(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
このウェブアプリケーションには3つのページがあります。
早速アプリケーションをスタートしましょう。コマンドdotnet run
でスタートができます.
ホームページはどのユーザーでもアクセスができます. Index.cshtml.cs
をご覧いただくと[AllowAnonymous] (
匿名を許可する)のアノテーションが使われております。
[AllowAnonymous]
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
キッチンページはEntra IDで保護されています。このページにアクセスすると、既存の認証セッションを確認され、存在しない場合はユーザーをログイン画面にリダイレクトされます。
テナント既存のアカウントでログインすると、ページが表示されます
次に、ヘッドシェフのみがアクセスできる在庫ルームページにアクセスします
アクセス不可!
在庫ルームのコードを見ると、ヘッドシェフ(head chef) Roleのアクセス権限が設定されています。
[Authorize(Roles ="HeadChef")]
public class StockRoomModel : PageModel
{
ログインしたユーザーにはこのRoleが割り当てられていないため、アプリケーションはページ表示のリクエストを拒否しました。
ではこのヘッドシェフ(head chef) Roleを作成し、ユーザーにアサインしましょう。
#「head chef」app roleを作成
az ad app update --id {先ほどのapp Id} --app-roles '[{ "allowedMemberTypes": [ "User" ], "description": "Only Head Chef has access to the stockroom.", "displayName": "Head Chef", "isEnabled": true, "value": "HeadChef" }]'
#app roleが作成された事を確認
az ad app show --id {先ほどのapp Id} --query "appRoles[?value=='HeadChef'].id" -o tsv
MicrosoftプラットフォームにはAzureロール, Entra ロール, またはApp ロールと様々なロールが存在します。当記事ではその違いついての説明するとかなり長文になってしまうので、ご興味ある方はこちらの投稿をご覧ください。今作成したロールはアプリケーション登録に関与している、Appロールだという事を知って頂ければ十分です。
次に、このロールをユーザーにアサインする必要があります。このApp ロールはAzure系統の物ではないため、残念ながらAzure CLIではアサインできません。Microsoft Graph APIを使用する必要があります。
このチュートリアルに従うのが最も簡単な方法です。
もっと挑戦したい方
Graph APIエンドポイントで同じことを行うこともできます。
ユーザーに必要なロールが割り当てられたので、ページに移動しましょう(ここでセッションをクリアする必要があるかもしれません)。
在庫ルームにアクセスできました!
当記事では、Microsoft Entra IDをRazor Pagesのウェブアプリケーションに統合し、細かなアクセス制御を実装しました。サービスプリンシパルやアプリケーション登録といった主要な概念を説明し、アクセス制御されたページを含む寿司屋アプリを作成しました。最後に、ロールで制限されたページにアクセスするための「Head Chef」Roleの作成とアサインをしました。
Microsoftプラットフォームで使用されるEntra IDロール、Microsoft 365ロール、Azureロール、Appロールの違いについて説明します。