はじめに
こんにちは!中途入社のなーがです。前回はAzure Service Local Fabric Clusterの環境構築方法についての内容でしたが、今回はMicrosoft Entra IDの「エンタープライズアプリケーション」と「アプリの登録」の違いでハマった話について書こうと思います。
解決方法だけ知りたい方は、こちらから確認できます。
作業内容
あるアプリケーションのインフラ環境を変更するために、新規構築したService Fabricクラスターへデプロイ先を切り替えようとしました。Azure上のService FabricクラスターへのデプロイはAzure Pipelinesで行っており、Azure PipelinesからService Fabricへの接続を行うための認証用Entra IDアカウントを旧クラスターで使用していたものから変更しました。
その後、デプロイを行ったのですが失敗してしまいました。
Pipelinesのリリースログを確認したところ、以下のエラーが発生していました。
ExceptionMessage: Exception calling "GetResult" with "0" argument(s): "AADSTS50105: Your administrator has configured the application XXXXXXXXXX_xxxxx ('XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') to block users unless they are specifically granted ('assigned') access to the application. The signed in user '{EmailHidden}' is blocked because they are not a direct member of a group with access, nor had access directly assigned by an administrator. Please contact your administrator to assign access to this application.
エラーコード:AADSTS50105より、認証アカウントがサービスプリンシパルへの権限を持っていないことが分かりました。
権限の確認
そこで、権限を確認するために、Azure Portalの「アプリの登録」にアクセスしました。
すべてのサービス > カテゴリ:ID > アプリの登録 > 「登録したいアプリケーション」> 所有者
すると、認証アカウントは所有者になっています。なぜ「アプリの登録」では所有者となっているのにも関わらず、権限エラーが発生したのでしょうか。
Pipelinesによるデプロイの流れ
まず、Pipelinesを使用したService Fabricのデプロイについて確認したいと思います。デプロイの流れは以下の公式ドキュメントにある通りです。
Pipelinesはデプロイ全体のオーケストレーションを行っており、CI/CDの実処理はPipelinesエージェントが実行します。その際に⑤の段階で以下の処理が行われます。
- PipelinesエージェントがService Connectionで指定されたEntra IDアカウントでEntra ID認証する
- 認証されたEntraIDアカウントがサービスプリンシパルを使用してService Fabricにアクセスする
アプリケーションオブジェクトとサービスプリンシパル
次に、Entra IDについてみていきます。Entra IDでは「アプリケーションオブジェクト」と「サービスプリンシパル」という認証の際に必須となる2つの概念があります。ここでは、これらの違いについて確認したいと思います。
公式ドキュメントによると、それぞれ以下のように説明されています。
Microsoft Entra アプリケーションは、その唯一のアプリケーション オブジェクトによって定義されます。アプリケーション オブジェクトは、アプリケーションの登録先の Microsoft Entra テナント (アプリケーションの “ホーム” テナントという) 内にあります。 アプリケーション オブジェクトは、1 つ以上のサービス プリンシパル オブジェクトを作成するためのテンプレートまたはブループリントとして使用されます。 サービス プリンシパルは、アプリケーションが使用されるすべてのテナントに作成されます。
アプリケーション オブジェクトから作成された具体的なインスタンスであり、そのアプリケーション オブジェクトから特定のプロパティを継承します。サービス プリンシパルは、アプリケーションが使用される各テナントに作成され、グローバルに一意のアプリ オブジェクトを参照します。サービス プリンシパル オブジェクトは、特定のテナントでアプリが実際に実行できること、アプリにアクセスできるユーザー、およびアプリがアクセスできるリソースを定義します。
つまり、「アプリケーションオブジェクトはサービスプリンシパルのひな形(テンプレート)、サービスプリンシパルはアプリケーションオブジェクトを基に作られたIDのようなもの」ということになります。オブジェクト指向プログラミングの経験がある方であれば、アプリケーションオブジェクトはクラス、サービスプリンシパルはインスタンスに該当するといった方がイメージしやすいと思います。
複数のクライアント(Entra ID)にまたがる場合はマルチテナントアプリケーションとなるのですが、詳しくは武井さんの記事で分かりやすくまとめられているのでこちらを見てみてください。
Azure Portalでは、アプリケーションオブジェクトは「アプリの登録」、サービスプリンシパルは「エンタープライズアプリケーション」で設定されています。
つまり、上記ではサービスプリンシパルではなくアプリケーションオブジェクトの設定を確認していたことになります。また、リソースにアクセスするためにはアプリケーションオブジェクトで作成した適切なアプリロールが、サービスプリンシパルで自分のアカウントに割り当てられている必要があります。
では、サービスプリンシパルで設定されているロールの割り当てを確認します。
すべてのサービス > カテゴリ:ID > Microsoft Entra ID > エンタープライズアプリケーション > 「登録したいアプリケーション」> ユーザーとグループ
解決方法
①権限ある人に追加してもらう
②自身のアカウントをサービスプリンシパルに追加する
解決方法としては上記の2つがありますが、今回は自身で設定できるようにするために②の方法について書こうと思います。公式ドキュメントより、以下の手順で行います。こちらでは画像付きでより詳しく説明されています。
- 「ユーザーまたはグループの追加」をクリック
- 「割り当ての追加」画面が表示されるので、ユーザーの「選択されていません」をクリック
- 画面右側に「ユーザーとグループ」画面が表示されるので、アプリケーションに割り当てるユーザーまたはグループを検索して選択する
- 「選択」をクリック
- 「割り当て」をクリック
再度デプロイしたところ、無事成功しました!
さいごに
今回はMicrosoft Entra IDの「エンタープライズアプリケーション」と「アプリの登録」の違いでハマった話について書きました。エラーの発生原因としては、サービスプリンシパルではなくアプリケーションオブジェクトの設定を確認していたこと、リソースにアクセスするために必要なロールが割り当てられていなかったためです。サービスプリンシパルやロールの設定はクラウドを扱う際に重要な権限周りの内容になるので、少しずつ使いこなせるようになろうと思います。