Microsoft Graph API を使用して ASP.NET Core Web アプリから M365 プロファイルにアクセスする

新型コロナウイルスの影響により在宅勤務が多くなり働き方改革が推進されるようになりました。特に Microsoft の Teams を導入する企業が多くなり、それと共に Office 365 を導入する企業も大変多くなりました。クラウドサービスを使用する上でのメリットはセキュリティ対応などの運用コストを抑えられることも然りですが、クラウド上のデータを活用できるというメリットもあります。今回は Microsoft Graph API を使用して、クラウド上のユーザデータを抽出して Web App に反映させるデモアプリを作成しながら、Graph API ってどんなものなのかをかみ砕いてみていきたいと思います！

#Microsoft Graph ってなーに？
Microsoft のドキュメントによると、Microsoft Graph には以下のような説明がありました。

>Microsoft Graph は、Microsoft 365 のデータとインテリジェンスにアクセスするための入り口です。 これにより、Microsoft 365、Windows 10、Enterprise Mobility + Security で膨大なデータにアクセスするために使用できる統合プログラミングモデルが提供されます。 Microsoft Graph の豊富なデータを使用して、数百万人のユーザーを操作する組織やコンシューマー向けのアプリを作成できます。

参考 : [Microsoft Graph の概要](https://docs.microsoft.com/ja-jp/graph/overview)

インテリジェンスにアクセスするための入り口？？？何言ってんだろう。。。
簡単に言うと、`Microsoft 365(Office 365)のデータを活用できる便利な機能` です。Microsoft 365 にはユーザデータやカレンダー、さらには Office 系のファイルなど様々なデータが含まれています。それらのデータに簡単にアクセスでき、そのデータを活用できる仕組みというわけです。(なかなか便利やん！)

以下は概要図になります。ちょっと難しいですが、少しはイメージできますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/987e6fe6-ff2a-6b3c-4a27-e940880b06a8.png)

>なるほど、Office 365 のデータを抽出できるんだねー。ん、ちょっと待てよ、そうすると自分のプロファイルとか色々、簡単に公開されちゃうわけ？？

と心配に思うかもしれませんが、そのようなことが内容にしっかりと認証をする仕組みが用意されています。逆にこの認証の仕組みを突破しないと Microsoft Graph は活用することができません。実装する上で一番引っ掛かりやすいところだそうなので、その方法をアプリを作成しながら見ていきたいと思います！

#Graph を活用した MVC アプリを作成してみよう！
今回作成してみたアプリは Microsoft が Graph のチュートリアルとして公開しているものです。以下の URL からその方法を参照できます。(英語サイト)
参考 : [Build ASP.NET Core MVC apps with Microsoft Graph](https://docs.microsoft.com/en-us/graph/tutorials/aspnet-core)

また、このチュートリアルは Microsoft の学習サイト `MS Learn` で確認することができます。(英語サイト)
参考 : [MS Learn : Build ASP.NET MVC web applications with the Microsoft Graph .NET SDK](https://docs.microsoft.com/en-us/learn/modules/msgraph-build-aspnetmvc-apps/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/d936dfaa-e5cf-691f-aa3f-0fd01b721374.png)

では実際に手順に従って、やっていきましょう！
※今回は Graph API の認証の周りに注力しているため、0からコードを書かず、GitHub にあるサンプルコードをダウンロードしました。じっくりやってみたい人はチュートリアルに従ってコードを書いてみると良いでしょう！

##GitHub のサンプルコードをダウンロードする
以下の GitHub レポジトリにサンプルコードがあります。ローカルにダウンロードし展開しておきましょう。
参考 : [GitHub のサンプルコード](https://github.com/microsoftgraph/msgraph-training-aspnet-core)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/38176032-3ac7-0a6c-cfe3-bfeccbf260c6.png)
ダウンロードできたら、`demo/GraphTutorial` にあるソリューションファイルを Visual Studio で開きましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/78c083d0-8bce-ffa3-5524-6559efbfc8a3.png)
こんな感じで開けたらOKです。

##必要な NuGet Package をダウンロードする
プロジェクトが開けたら必要な NuGet Package をダウンロードします。今回必要な NuGet Package は以下3つです。
①Microsoft.Identity.Web
https://www.nuget.org/packages/Microsoft.Identity.Web/
②Microsoft.Identity.Web.UI
https://www.nuget.org/packages/Microsoft.Identity.Web.UI/
③Microsoft.Graph
https://www.nuget.org/packages/Microsoft.Graph/

一個一個 NuGet Package Manager からダウンロードしても良いですが、めんどくさいので Nuget Package コンソールから一括でインストールしておきましょう。

```powershell
dotnet add package Microsoft.Identity.Web --version 0.1.3-preview
dotnet add package Microsoft.Identity.Web.UI --version 0.1.3-preview
dotnet add package Microsoft.Graph --version 3.5.0
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/25b75268-6486-c0dc-b874-ea296e5a3a3b.png)

これでアプリのコード自体は揃いました。あとは AAD のアプリ登録をやっていきます！

##AAD でアプリを登録する
Microsoft Graph を呼び出すには、アプリが Microsoft ID プラットフォームからアクセス トークンを取得する必要があります。Office 365 管理センターから Azure AD にアクセスし、Portal ページで登録と確認ができます。これは管理者アカウントでないとできないので、管理者が別にいる会社のアドレス等ではできません!
動作を試して見たい場合は Office 365 Dev Center から Office 365 テナントを登録することもできます。少しめんどくさいですがご了承ください。(検証用テナントなんて作れんよ！という方は画像をぺたぺた張っていきますのでそちらをご覧いただきイメージください)
参考 : [検証用 Office 365 テナントを作成するための Dev Center リンク](https://developer.microsoft.com/ja-jp/office)

Office 365 管理センターにアクセスすると、右のメニューに `Azure Active Directory` があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/b6907841-9539-c263-2264-5b86a6805e2b.png)
Azure Active Directory をクリックすると、Azure Active Directory 管理センターにリンクします。
AAD を選択すると、左メニューにアプリ登録というボタンが見えるので、クリックします。(検証用のテナントは適当に"北部中学校"という名前を付けています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/088f917d-41e2-d149-0bb5-84e3802b9cb8.png)
「新規登録」から新しいアプリを登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/8cbe8d18-16eb-2659-10c4-8df7a0798c2d.png)
適当な名前を付けてアプリを登録したあとに、リダイレクト URL を設定します。今回はローカルでデバッグするアプリケーションを使用するため、以下のリダイレクト URL を設定します。

```
//リダイレクト URL
https://localhost:5001/signin-oidc
https://localhost:5001/

//ログアウト URL
https://localhost:5001/signout-oidc
```

次にクライアントシークレットを設定します。新しく「Forever」という名前のシークレットを作成して、値をコピーしておきます。この値は作成するときにしかコピーできないので忘れずにコピーしておきましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/d9a7d5fc-163f-f22a-7d4f-a8d86e49f738.png)

これで AAD 側でアプリ登録が完了しました。ここで作成したクライアント ID と、クライアントシークレットはこの後使用するので忘れずにコピーしておきます。

##アプリ側で AAD 認証をする
次にアプリ側で AAD 認証の設定を行います。サンプルスクリプトの `appsettings.json ` を以下のように書き換えます。

```appsettings.json
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
```

これでアプリケーションをデプロイすると、認証が求められるようになります。次に、CLI でこのプロジェクトがあるディレクトリを開き、以下を実行します。

```
dotnet user-secrets init
dotnet user-secrets set "AzureAd:ClientId" "さきほどコピーしたクライアント ID"
dotnet user-secrets set "AzureAd:ClientSecret" "さきほどコピーしたクライアントシークレット"
```

これで先ほど AAD でアプリ登録した ID に対して認証を実施するように設定できました。あとは実行するだけです！！

##アプリをデプロイして O365 アカウントでログインしてみる
では実際にアプリをデプロイしてみましょう。まずは O365 の検証環境に二つのアカウントを作成し、それぞれ違うデバイス(ここでは VM 上にふたつの Win10 環境を作成し検証しています)の Teams アプリにログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/de564d19-aaa1-a0b5-9012-ee638dc93d55.png)
アプリケーションを実行して、アカウントでサインインすると、右上にサインインされたっぽいロゴが出てきてアプリのトップページが表示されます。(うまくアプリ登録が行っていない場合はここでエラーが発生します)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/4d07f057-2583-16d1-1a0c-bcd297874dcb.png)
上のメニューのカレンダーをクリックすると、Teamsで設定したカレンダーを表示させることができます。これは Graph API 経由で取得したユーザーのカレンダーを表示させています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/2abbb7bc-e21b-9380-67a8-efca769fc2a6.png)
さらに、新しい会議を設定してみます。今回のサンプルアプリではカレンダーに予定を追加できる様になっています。また、同じAADのユーザーを招待することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/c9d2adc3-a334-43b0-f788-53f2dda307d8.png)
新しい予定を設定すると アプリ側のカレンダーに予定が反映されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/06d15911-b2cb-87e7-b8f7-7cc9816f052d.png)
検証環境での Teams スケジュールにも、アプリから設定した予定が反映されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/a8544e11-ccc1-b162-fbaa-db3fcdee4e37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/df6a937c-0dde-fd1e-f0cb-1071036f5d1f.png)

#まとめ
今回みてきたように、Graph API を使用すれば Office 365 の様々なデータにアクセスできます。一番やっかいなのは認証の部分ですが、そこさえうまく設定できれば、ユーザーのカレンダー情報だけでなく、メールの内容やチームスのチャットの内容といった様々なデータにアクセス可能です。
働き方改革として O365 が導入された次のステップとして、「データ活用」という観点でぜひ試して見たい機能かな、と思いました。