💨

Entra IDのアプリの登録について

2024/04/10に公開

はじめに

業務でAzure ADを使う機会があり、アプリの登録周りでちゃんと理解しないまま進めた箇所があったため整理する。

基本的には以下の資料で理解を進めた。一部自分の理解不足な箇所があったため、そこを重点的に書き起こす。
サポートブログにはいつもお世話になっております。

https://jpazureid.github.io/blog/azure-active-directory/oauth2-application-resource-and-api-permissions/

サービスプリンシパルとは

Azureではないアプリケーションが、Azureリソースにアクセスするための資格情報

「APIの公開」と「スコープ」について

自作のAPIをユーザに公開したい場合には「APIの公開」が必要。
「スコープ」を設定することで、機能をより細かく分割できる。このスコープレベルでアクセストークンを取得することになる。
スコープからアクセストークンを取得したのちに、HTTPヘッダーにトークンをセットしてAPIアクセスを行う。

こちらは以下の記事も参考にして理解を進めた。
https://tech-lab.sios.jp/archives/23371

APIを自作した場合のMicrosoft Graphへのアクセスの流れは以下のイメージと理解した。
alt text

スコープについて1

質問

いずれも、初歩的な質問になりますが、誤った理解を防いでおきたく確認させてください。
Microsoft Graph APIの呼び出しに関連した質問になります。そのため、任意のリソースサーバに対しての呼び出しではありません。

質問1

scopeを使った時の、Microsoft Graph APIの呼び出しについてあるべき姿を教えてください。
利用者が定義したscopeからアクセストークンを取得し、
Microsoft Graph(アプリの登録時にデフォルトで作成済み)に渡すことで、Microsoft Graph経由でMicrosoft Graph APIを呼び出すのは想定していない使い方だと感じました。
scopeから受け取ったアクセストークンを使って、Microsoft Graph APIを直接呼び出すことが望ましいと考えています。
(例えば、JavaScriptであれば以下のcallMSGraphにトークンを渡して直接Graph APIの呼び出し)
https://learn.microsoft.com/ja-jp/entra/identity-platform/tutorial-v2-javascript-auth-code#call-the-microsoft-graph-api

認証相違ないでしょうか?

質問2

scopeでは自作のAPIを作成できる機能と認識しています。
>スコープ名は Microsoft Graph API に倣って XXX.Read のように設定しましたがアプリの構成に従い好きな名前をつけて OK です。

サポートブログの上記の記載について、scope名が任意でよい理由について教えてください。
利用者への承認のポップアップの画面表示で使われるだけであり、実際のGraph APIを呼び出す時に、必ずしも設定したスコープ名でのリクエストでないからと認識しています。
例えば、User.Read.Sytem1というスコープ名で画面表示した場合には、プログラム上ではMicrosoft Graph APIで決まっているアクセス許可(例User.Read)を呼び出す処理にする必要があると考えています。
上記のような実装で、Microsoft Graphと同じようなAPIを自作することも可能と考えています。

認証相違ないでしょうか?

回答

scope の機能についてイメージを掴んでいただくことがよろしいと思われますので、scope の詳細についてご案内させていただきます。

scope はアプリケーション毎に定義されたアクセス許可のセットを示します。
例えば、Microsoft Graph API ではユーザーの読み取りを実行するためのアクセス許可に User.Read という scope 名を定義しています。

参考 : Microsoft ID プラットフォームでのスコープとアクセス許可
https://learn.microsoft.com/ja-jp/entra/identity-platform/scopes-oidc


これらのリソースのいずれでも、機能をより小さいまとまりに分割するために使用できるアクセス許可のセットを定義できます。 たとえば、Microsoft Graph では、特に次のタスクを実行するアクセス許可が定義されています。
 ・ユーザーの予定表の読み取り
 ・ユーザーの予定表への書き込み
 ・ユーザーとしてのメールの送信
これらの種類のアクセス許可が定義されていることで、リソースでは、データと、API 機能を公開する方法を、きめ細かく制御できます。

(中略)

OAuth 2.0 では、これらの種類のアクセス許可セットは "スコープ" と呼ばれます。 "アクセス許可" と呼ばれることもよくあります。


この scope はリソース毎に固有であり、そのリソースに対するアクセス トークンを取得する際にのみ利用されます。
Microsoft Graph API を呼び出す際には Microsoft Graph API で定義された scope を指定してアクセス トークンを取得します。

一方、お客様で独自の API を利用する場合、アプリケーション側であらかじめ任意の scope 名を定義します。
ただし、お客様のアプリケーションで定義された scope を指定して取得したアクセス トークンは、お客様のアプリケーション上の API を実行するためのトークンであるため、そのトークンを利用して Microsoft Graph API を呼び出すことはできません。
もし、Microsoft Graph API を呼び出す必要があるのであれば、Microsoft Graph API で定義された scope を指定する必要がございます。

任意の scope を定義する機能は、お客様のアプリケーションで独自の API を提供するような仕組みが構成されている場合にのみ利用する機能とご認識くださいませ。

スコープについて2

追加質問

ただし、お客様のアプリケーションで定義された scope を指定して取得したアクセス トークンは、お客様のアプリケーション上の API を実行するためのトークンであるため、そのトークンを利用して Microsoft Graph API を呼び出すことはできません。もし、Microsoft Graph API を呼び出す必要があるのであれば、Microsoft Graph API で定義された scope を指定する必要がございます。

ユーザが作成したAPIに、user.readのようなMicrosoft Graph APIと同じスコープを定義した場合には、取得したアクセストークンを用いてMicrosoft Graph APIを呼び出すことは可能という認識でよいしょうか。実際に上記を実装する予定はないのですが、スコープの仕組みとして知っておきたいと考えています。

回答

ユーザーが作成したAPIに、user.readのようなMicrosoft Graph APIと同じスコープ名を定義した場合でも、取得したアクセストークンを用いてMicrosoft Graph APIを呼び出すことはできません。

以下に詳細をご案内させていただきます。

スコープはリソース毎に固有であり、リソース識別子 (アプリケーション ID の URI) と定義したアクセス許可値を組み合わせた文字列で構成いたします。
リソース識別子はグローバルで一意な値であり、自作のアプリの初期値では “api://appid” が設定されます。
また、Microsoft Graph では https://graph.microsoft.com がリソース識別子でございます。

例えば、ユーザーが作成した API を呼び出す場合には "scope=api://appid/user.read" のような形でスコープを指定してアクセス トークンを取得します。
一方、Microsoft Graph API を呼び出す場合には "scope=https://graph.microsoft.com/user.read" のような形でスコープを指定します。

上記で取得したアクセス トークンはリソース識別子が一致するリソースでのみ利用可能でございます。
同じ user.read であっても自作の API に対するスコープ (api://appid/user.read) と Microsoft Graph API に対するスコープ (https://graph.microsoft.com/user.read) は異なるものであり、自作の API 用に取得したトークンを利用して Microsoft Graph API を呼び出すことはできません。

なお、Microsoft Graph は例外的にスコープでリソース識別子を指定せずともアクセス トークンを取得可能です。
これはMicrosoft ID プラットフォームではスコープのリソース識別子が省略されている場合、暗黙的に Microsoft Graph に対する要求と見なす仕様が存在しているためでございます。

参考 : Microsoft ID プラットフォームでのスコープとアクセス許可
https://learn.microsoft.com/ja-jp/entra/identity-platform/scopes-oidc

----- 抜粋 -----
Microsoft ID プラットフォームの承認サーバーへの要求では、スコープ パラメーターでリソース識別子が省略されている場合、リソースは Microsoft Graph と見なされます。 たとえば、scope=User.Read は、https://graph.microsoft.com/User.Read と同じです。
----- 抜粋 -----

案件でどう使っていたか

alt text
自作したAPIからアクセストークンを取得して、APIMでのJWT検証をしていた。
スコープはAllとして、今回は細かく制限していなかった。もしも細かくAPIの権限を制御するようであれば要検討である。
委任されたアクセスとしては、指定したスコープにアクセスすると、承認画面がポップアップで出る。

memo

委任されたアクセス と 管理者の同意ってどういう関係?
→ 前者はユーザがアプリに権限を許可(委任)する。後者は、アプリケーション権限を与えるときに、管理者として問題ないことを許可する同意のこと。

Discussion