【GraphAPI】アプリケーション許可権限 (2)：Graph API の実行

# はじめに

※ この投稿は以下の記事の続きです。

https://qiita.com/atsmin77/private/a31198368c4a570b801a

前回の記事で、アプリケーション許可権限で Graph API を実行するために必要なアクセストークンを取得することができました。この記事では、Graph API を実際に実行する手順を紹介しています。

# 2. Graph API の実行

Graph API を実行するには、以下の手順を実施します。

1. Entra ID アプリケーションにアクセス許可を追加する
1. プログラムで Graph API を実行する

## 2.1 Entra ID アプリケーションにアクセス許可を追加する

### 2.1.1 アクセス許可が無い場合

アプリケーション許可権限では、管理者があらかじめ許可した操作のみ Graph API で行うことができます。

試しに、**[Application] - [Users]** とフォルダを展開して、**[Get users]** をクリックしてみます。これはテナント内のユーザー情報を取得する Graph API です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/3a8622c7-4993-4ba9-85d6-68e3f96a7a96.png)

::: note
[前の記事の手順](https://qiita.com/atsmin77/private/a31198368c4a570b801a#124-アクセストークンの取得) で取得したアクセストークンは、**[Application]** フォルダ配下で Graph API を実行する際に利用されます。
:::

::: note warn
**[Delegated]** フォルダはユーザー委任権限で Graph API を実行する場合に使用します。この記事の[最後](#ユーザー委任権限で実行する方法)で紹介しています。
:::

**[Send]** ボタンをクリックすると、Graph API が実行され、画面下側に実行結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/86999ae9-652a-410c-bea7-2f0aa02a513d.png)

[ステータス](https://qiita.com/atsmin77/items/a1d53031b120da5d9697#http-%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89) が **"403 Forbbiden"** となり、**[Preview]** に以下のメッセージが出力されています。これは、Entra ID アプリケーションにユーザー情報を取得するアクセス許可がないことを表しています。

```
"message": "Insufficient privileges to complete the operation."
```

### 2.1.2 必要なアクセス許可の確認

各 Graph API の公開情報で **[アクセス許可]** のセクションに必要なアクセス許可が記載されています。

アプリケーション許可権限で Graph API を実行する場合は、**[アプリケーション]** の行を確認します。

(参考：ユーザーを一覧表示する)
https://learn.microsoft.com/ja-jp/graph/api/user-list?view=graph-rest-1.0&tabs=http
> アクセス許可
アクセス許可の種類	アクセス許可 (特権の小さいものから大きいものへ)
...
アプリケーション	User.Read.All、User.ReadWrite.All、Directory.Read.All、Directory.ReadWrite.All

ユーザー情報を取得する Graph API の公開情報を確認すると、**"User.Read.All"** が [最小特権アクセス許可](https://qiita.com/atsmin77/items/a1d53031b120da5d9697#%E6%9C%80%E5%B0%8F%E7%89%B9%E6%A8%A9%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E8%A8%B1%E5%8F%AF) であることが分かります。

### 2.1.3 アクセス許可の追加方法

Graph API を実行するために必要なアクセス許可は、管理者が Entra ID 管理センターからアプリケーションに追加します。

::: note
管理者には [特権ロール管理者](https://qiita.com/atsmin77/items/b6bd8def4b9ddc5ab49b#%E7%AE%A1%E7%90%86%E8%80%85%E3%81%AE%E5%90%8C%E6%84%8F%E3%82%92%E8%A1%8C%E3%81%86%E3%81%9F%E3%82%81%E3%81%AB%E5%BF%85%E8%A6%81%E3%81%AA%E7%AE%A1%E7%90%86%E8%80%85%E3%83%AD%E3%83%BC%E3%83%AB) の役割が必要です。
:::

1. **[アプリケーション] - [アプリの登録]** よりアプリケーションを選択し、**[API のアクセス許可] - [+アクセス許可の追加]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/a785ff1f-d9b6-432b-9024-5f0e3995369d.png)
1. **[Microsoft Graph]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/56af777b-ee53-4075-8f1c-0be85f0016e6.png)
1. **[アプリケーション許可]** をクリックし、検索ボックスに **"User.Read.All"** と入力します
**[User.Read.All]** に ✅ を付け、**[アクセス許可の追加]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/fc9cba20-c038-47e7-b0a5-83c90f7b4580.png)
1. **[【テナント名】に管理者の同意を与えます]** をクリックします
確認ダイアログが表示されるので **[はい]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/4cb418cd-4bcf-4b1a-af7b-65c0a3973821.png)
1. **[【テナント名】に付与されました]** と表示されることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/3eefc6e8-c7f2-4037-9e52-efbb7f7143f1.png)

## 2.2 プログラムで Graph API を実行する


### 2.2.1 ユーザー情報の取得
アクセスを許可を追加したら、[同じ手順](https://qiita.com/atsmin77/private/d4f1572954bd2db32ea5#124-%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AE%E5%8F%96%E5%BE%97) で再度アクセストークンを取得します。

::: note warn
アプリケーションのアクセス許可を変更したら、その都度アクセストークンの再取得が必要です。
:::

再度ユーザー情報を取得する Graph API の **[Send]** ボタンをクリックすると、今度はステータスが **[200 OK]** と表示され、**[Preview]** に結果が出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/2f49588f-eaa6-456f-8e21-848b2789a475.png)

#### アクセストークンからアクセス許可を調べる方法

::: note
アクセストークンには、アクセストークンを取得した時点のアクセス許可の情報が含まれています。
:::

アクセストークンに含まれるアクセス許可の情報は [jst.ms](https://jwt.ms/) というサイトで確認することができます。

1. 取得したアクセストークンを Ctrl + A で全選択してコピーします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/9b3fbe71-0ee6-4deb-800a-ad9daf1ae7ed.png)
1. アクセストークンを jst.ms の画面上部に貼り付けます
1. **"roles"** にアクセス許可が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/ff0bd32b-fa0d-40f9-b230-ba541e32b42a.png)

::: note
[ユーザー委任権限で取得したアクセストークン](#ユーザー委任権限で実行する方法)の場合は **"scp"** にアクセス許可が表示されます。
:::

(参考：API Permissions not updated when using Microsoft Graph)
https://learn.microsoft.com/en-us/answers/questions/1824515/api-permissions-not-updated-when-using-microsoft-g

### 2.2.2 チームの作成

今度は、チームを作成する Graph API を実行してみます。以下の公開情報を見ながら URL と送信データを設定します。

(参考：チームを作成する)
https://learn.microsoft.com/ja-jp/graph/api/team-post?view=graph-rest-1.0&tabs=http

#### URL と送信データの設定

左側の検索ボックスに **"Create Team"** と入力して、**[Application] - [Teams]** とフォルダ配下の **[Create team]** をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/1bbb97bb-6377-4387-bccf-ae8918622638.png)

■ URL の変更

URL を公開情報と合わせて以下に置き換えます。

> HTTP 要求
> POST /teams

```
https://graph.microsoft.com/v1.0/teams
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/5e05e369-c20b-4039-8b4f-6cc84c166ff7.png)

■ 送信データの設定

作成するチームの名前などの情報を送信データとして **[Body]** タブで指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/53634795-1834-4146-a1b1-f7dc4f35d730.png)

送信データは JSON 形式で指定します。どのように指定すれば良いのかは公開情報に例が記載されています。

>例 2:アプリケーションのアクセス許可
{
   "template@odata.bind":"https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
   "displayName":"My Sample Team",
   "description":"My sample team’s description",
   "firstChannelName": "My first channel of the sample team",
   "members":[
      {
         "@odata.type":"#microsoft.graph.aadUserConversationMember",
         "roles":[
            "owner"
         ],
         "user@odata.bind":"https://graph.microsoft.com/v1.0/users('0040b377-61d8-43db-94f5-81374122dc7e')"
      }
   ]
}

| 設定箇所 | 意味 |
|:-:|:-:|
| displayName | チーム名 |
| description | 説明 |
| firstChannelName | 最初のチャネルの名前 |

**"members"** に所有者となるユーザーの ID を指定します。

| 設定箇所 | 意味 |
|:-:|:-:|
| roles | 追加するユーザーのロール<br>所有者 (owner) またはメンバー (member) |
| user@odata.bind | 追加するユーザーの ID  |

::: note
[ユーザー委任権限の場合](https://qiita.com/atsmin77/items/a1d53031b120da5d9697#32-%E9%80%81%E4%BF%A1%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%A8%AD%E5%AE%9A) は Graph API を実行する際にサインインしたユーザーが自動的にチームの所有者になります。アプリケーション許可権限では送信データの "members" で任意のユーザーをチームの所有者に設定します。
:::

送信データの例：
```
{
   "template@odata.bind":"https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
   "displayName":"テストチーム02",
   "description":"アプリケーション許可権限で作成したテストチームです。",
   "firstChannelName": "テストチャネル",
   "members":[
      {
         "@odata.type":"#microsoft.graph.aadUserConversationMember",
         "roles":[
            "owner"
         ],
         "user@odata.bind":"https://graph.microsoft.com/v1.0/users('c1fe9cb2-87f9-4a6a-b040-a5b63108dc4e')"
      }
   ]
}
```

#### アクセス許可の追加

公開情報の **[アクセス許可]** のセクションから、必要なアクセス許可を確認します。

>アクセス許可
アクセス許可の種類	最小特権アクセス許可	より高い特権のアクセス許可
...
アプリケーション	Team.Create	Directory.ReadWrite.All、Group.ReadWrite.All、Teamwork.Migrate.All

最小特権アクセス許可は **"Team.Create"** と記載されています。[同じ手順](#213-アクセス許可の追加方法) で Entra ID アプリケーションにアクセス許可を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/3a2e01fc-6493-468b-88ad-f5df4563586e.png)

アクセス許可を追加したら、再度アクセストークンを取得して、**[送信]** ボタンをクリックします。

ステータスが **[202 Accepted]** と表示されることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/00a5c0e2-0b28-4a40-991f-e3b358101e84.png)

::: note
作成したチームの ID は、**[Headers]** タブの **[content-location]** に含まれています。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/3bf7c794-c4d0-461f-8ea0-d3bab116452e.png)

Teams 管理センターから確認すると、チームが作成されていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/2724a4a4-d96e-46f3-965d-bae71f6d8343.png)

### 2.2.3 その他の Graph API の実行

その他の Graph API についても、同じ方法で実行することができます。

[Application] フォルダの中に実行したい Graph API が無い場合には、以下の方法で追加します。

1. [Application] フォルダを右クリックして **[HTTP Request]** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/2a233ec4-0468-4c84-9cde-b1e9670cf654.png)
1. **[New Request]** を右クリックして、実行したい Graph API の名前を入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/0757fc76-535a-4114-a0cd-6980b2455049.png)
1. 実行したい Graph API の公開情報を確認して、URL や送信データを設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/a4898e87-57bd-4b77-b783-57d163dd7757.png)

# 補足

## ユーザー委任権限で実行する方法

Insomnia を使って [ユーザー委任権限](https://qiita.com/atsmin77/items/31df2f5624840b45dda0#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%A7%94%E4%BB%BB%E6%A8%A9%E9%99%90) で Graph API を実行することもできます。

[Graph Explorer](https://qiita.com/atsmin77/items/a1d53031b120da5d9697) からも実行することはできますが、Insomnia を使うとよく使用するリクエストを保存しておくことができるので便利です。

1. **[Delegated]** フォルダをクリックして、**[Auth]** タブに以下を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/58bbc111-cc97-441d-bf3a-ba0dbdf2dae5.png)
   | 項目 | 内容 |
   |:-:|:-:|
   | Redirect URL | https://insomnia.rest |
   | SCOPE | Graph API の実行に必要なアクセス許可 |

   ::: note warn
   **[Redirect URL]** は Entra ID へ登録したアプリケーションの [リダイレクト URI](https://qiita.com/atsmin77/items/a31198368c4a570b801a#11-entra-id-%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2) と一致している必要があります。
   :::
   ::: note
   **[SCOPE]** には必要なアクセス許可を<ins>スペース区切り</ins>で入力します。
   例：Team.ReadBasic.All Team.Create
   :::
1. **[Auth]** タブを下にスクロールして、**[Fetch Token]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/406697aa-6908-4233-8d05-69a599c0c985.png)
1. サインインを促すダイアログが表示されるので、Graph API を実行するユーザーでサインインします
1. アクセス許可の同意に関するダイアログで **[承諾]** をクリックします
   その後白い画面が表示されるので右上の × ボタンからウィンドウを閉じます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/fef4caa0-2b33-4096-8a05-5ac111100e52.png)
1. 取得されたアクセストークンが **[ACCESS TOKEN]** に表示されることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/aff09581-dba6-4abe-84dd-7ebe4cf67bc4.png)
1. **[Delegated]** フォルダ配下のリクエストを実行します
   以下の例ではサインインしたユーザーが所属しているチームの一覧を取得しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/466398e8-e394-4422-812f-15042d98c5da.png)

(参考：joinedTeams を一覧表示する)
https://learn.microsoft.com/ja-jp/graph/api/user-list-joinedteams?view=graph-rest-1.0&tabs=http

## Insomnia のクラウドへ同期する方法

コレクションを Insomnia のクラウドへ同期すると、他のマシンでもクラウドから同期して作業を継続することができるので便利です。

サーバへの同期は以下の手順で行います。

::: note
**[Microsoft Graph]** Collection と **[M365 Environment]** の両方について、以下の手順でクラウドへ同期します。
:::

1. [Microsoft Graph] Collection を開いた状態で、左下のアイコンをクリックし **[Commit]** を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/2b466a03-9a93-435d-bf18-12c4dd3e1061.png)
1. **[Changes]** に最後に同期されてから変更された内容が表示されます
   サーバ側へ同期したい変更内容を **[+]** ボタンで選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/8d9e2f3b-b8c2-4f62-88c4-98b8331247bf.png)
1. 選択した変更内容が **[Staged changes]** に表示されていることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/1e80bf45-0b64-439c-9fdd-78d08eb3f5a8.png)
1. **[Message]** に変更内容などを記載して、**[Commit and push]** をクリックすると、クラウドへ同期されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/04eec010-117b-496b-91aa-ab608bdbe624.png)
1. [M365 Environment] についても同じ手順で同期します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/25e6e13d-5cd5-4a80-815d-b06664c659d0.png)
1. 他の端末でクラウドと同期する時は **[Pull]** をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/25dee4f9-6fc7-4fde-8c63-9615954bb391.png)

::: note
**[History]** から **[Restore]** を選択することで、いつでも **[Commit]** したタイミングの状態に戻すことができます。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/3316d0c6-8d6b-4a39-975a-f0011f543255.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/2e0b82d9-d935-4e97-966d-362cb13fb448.png)