Azure Bot Service (V4) による Office 365 ユーザー認証を試してみる (2018年12月版)

チャットボットからユーザー認証を行って、ユーザー情報を利用したり、カスタマイズ機能を提供したりする、というのはよく想定されるシナリオかと思います。
Azure Bot Service には OpenID プロバイダーを利用した OAuth 認証機能が組み込まれており、各種設定をすることで簡単に利用できます。
今回は Azure Bot Service (Bot Framework ベースのチャットボット Web アプリ) で、Office 365 ユーザー認証を利用する手順を紹介します。

>公式ドキュメント
[docs.microsoft.com > Azure > Azure Bot Service を介してボットに認証を追加する (Bot Framework V4)](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0)

# ポイント

Azure のサブスクリプション管理者(アカウント) と Office 365 の管理者(アカウント) が同一でないケースを踏まえ、

- 最初に Office 365 管理者アカウントで Office 365 テナントに紐づくアプリ登録 (= App ID と App Password を取得) を行います 
- アプリ登録で発行された App ID と App Password を用いて、Azure サブスクリプションの管理者アカウントで Azure Bot Service 側の設定を行います

# 準備

- Office 365 アカウント
    - チャットボットに必要な権限を付与できる管理者ユーザーなどをご準備ください。Azure サブスクリプションの管理者と同一である必要はありません
    - 今回は、[Office 365 Business Premium](https://products.office.com/ja-jp/business/office-365-business-premium) の無料試用版を利用しています

以下 Azure Bot Service を作成、利用するための準備です。詳細は [Azure Bot Service × Bot Framework V4 のはじめかた](https://qiita.com/annie/items/8183189eb68a04a3de76) をご覧ください。

- Microsoft アカウント & Azure サブスクリプション
    - 無料評価版でも問題ありません
    - [準備方法](https://qiita.com/annie/items/cf93a7a832123946a7da#%E6%BA%96%E5%82%99)
- [Bot Framework V4 Sample](https://github.com/Microsoft/BotBuilder-Samples)
    - GitHub に公開されているサンプルコードを利用しますので、使いたい言語、サンプルをローカルにダウンロードして用意しておきます
    - C# の場合: [18.bot-authentication](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/18.bot-authentication) または [24.bot-authentication-msgraph](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/24.bot-authentication-msgraph)
    - Node.js の場合: [18.bot-authentication](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/18.bot-authentication) または [24.bot-authentication-msgraph](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/24.bot-authentication-msgraph)
- C# or Node.js の開発ツール、開発＆稼働環境
    - IDE として [Visual Studio 2017](https://visualstudio.microsoft.com/ja/vs/) (Win/Mac ※無償版のCommunity でOK) または [Visual Studio Code](https://code.visualstudio.com/) (Win/Mac/Linux) など
    - Node.js で IDEで稼働環境をインストールしていない場合は、ローカルに Node.js および npm をインストールして準備しましょう
- [Bot Framework Emulator](https://github.com/Microsoft/BotFramework-Emulator/releases/tag/v4.1.0)
    - チャットボットの動作を確認するためのツール (Win/Mac/Linux)。今回は v4.x版を利用しています

# 手順

- [1. Microsoft App Portal で新規アプリの登録](#1-microsoft-app-portal-%E3%81%A7%E6%96%B0%E8%A6%8F%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E7%99%BB%E9%8C%B2)
- [2. Azure Portal から Azure Bot Service の新規作成](#2-azure-bot-service-%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90)
- [3. Bot Framework サンプルコードを利用した認証の確認](#3-bot-framework-%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E8%AA%8D%E8%A8%BC%E3%81%AE%E7%A2%BA%E8%AA%8D)


# 1. Microsoft App Portal で新規アプリの登録

[Microsoft App Registration Portal](https://apps.dev.microsoft.com/) をブラウザーで開き、**Office 365 アカウント** でサインインします。**[アプリの追加]** をクリックします。
![20181220_01.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/e473bfa9-0ad8-1e81-451b-f6b06a758088.png)

アプリケーションの名前 (自分で識別しやすいもの) を入力し、**[Create]** をクリックして新規作成します。
![20181220_02.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/e5089031-6db9-29a9-3232-f67aac9b0eec.png)

アプリケーション登録画面が表示されます。
表示される **アプリケーション ID** (*App ID*) をコピーしてローカルに保存しておきます。
*アプリケーションシークレット* の欄にある **[新しいパスワードを生成]** をクリックして、パスワードを生成します。
![20181220_03.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/8d32430e-4e9e-c2c2-4a49-6b4dfef45c92.png)

表示されるパスワード (*App Password*) をコピーして、先ほど保存した *App ID* とセットでローカルに保存しておきます。
![20181220_04.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/5ae45d74-f9ae-c2d2-161c-979ec4a55230.png)

> パスワードは作成時に表示されるのみ、今後二度と表示されません。分からなくなった場合は再作成を行います。

アプリケーション登録画面に戻り、ページ中腹にある **プラットフォーム** の欄にある **[プラットフォームの追加]** をクリックします。
![20181220_05.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/f29ac961-d97e-1a0a-847d-6a29b85eef86.png)

*プラットフォームの追加* 画面で **Web** を選択します。
![20181220_06.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/0ebacb03-925b-a4ce-7d20-8b2cf29ee6c6.png)

Web プラットフォームが追加されたら、以下のように設定を行います

- 暗黙的フローを許可する: オン(☑)
- リダイレクト URL: https://token.botframework.com/.auth/web/redirect
- ログアウト URL: (空白のまま)

![20181220_07.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/2504d27e-2021-9dbc-1410-27b7cc3d86f7.png)

さらに、アプリケーション登録画面の **Microsoft Graph のアクセス許可** の欄にある *委任されたアクセス許可* の **[追加]** をクリックします。
![20181220_08.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/076b3bfc-8bd8-1aed-70e9-c19547a1b7c5.png)

デフォルトでサインインとユーザー情報取得を行う User.Read が付与されています。今回は、OpenID を利用する **openid** と **profile**、Microsoft Graph により Office 365 上の情報を取得＆操作する **Mail.Read**、**Mail.Send**、**User.ReadBasic.All** を選択して追加しておきます。
![20181220_09.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/c589443b-8a3e-5a4a-21a8-e715dd2fb569.png)

アプリケーション登録画面下部の **[保存]** をクリックして登録した情報を保存します。
![20181220_10.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/d907098a-f292-5c4a-57af-c11c7cd30e52.png)


# 2. Azure Bot Service の新規作成

[Azure Portal](https://portal.azure.com) から Azure サブスクリプション が 紐づいたアカウントでサインインします。 
[+新規作成] をクリック、**Bot Service** と検索して **Web App Bot** を新規作成します。 
![20181220_11.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/f6824035-c48a-a26f-7da3-d1667a8c4f1b.png)

> Azure Bot Service の認証機能を使うだけなら Bot Registration でも OK です。ここでは最終的にアプリをアップロードすることも踏まえて Web App を選択しています。

Bot Template は V4 を選択、 Basic Bot のままでも構いませんが、より単純な Echo Bot に変更しています。言語は C# または Node.JS から選択してください。
![20181220_12.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/c7035359-df90-e407-9b2f-d85fe28e959a.png)

また、Microsoft App ID とパスワードは自動作成せず、[1.](#1-microsoft-app-portal-%E3%81%A7%E6%96%B0%E8%A6%8F%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E7%99%BB%E9%8C%B2) で作成した AppID と パスワードを入力します。
![20181220_13.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/70bfba62-f66e-7cb5-a2a5-b1438792b78c.png)

**[作成]** をクリックして、Azure Bot Service を作成します。

Bot Service が作成されたら表示して、メニューから **[設定]** をクリックします。Bot Service の設定 ブレードの一番下にある **OAuth 接続設定** の欄にある **[設定の追加]** をクリックします。
![20181220_14.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/9b791268-1e74-2328-da8c-f927e9282912.png)


新しい接続設定ブレードで以下のように設定します。

- Name: (ご自身で識別しやすいものを) ※ローカルに保存しておきます
- サービスプロバイダー: Azure Active Directory V2
- Client Id: ローカルに保存しておいた App ID
- Client Secret: ローカルに保存しておいた App Password
- Tenant ID: common
- スコープ: [1. Microsoft App Portal で新規アプリの登録](#1-microsoft-app-portal-で新規アプリの登録) で選択した*Microsoft Graph のアクセス許可* を入力します。(今回は **Mail.Read Mail.Send openid profile User.Read User.ReadBasic.All**)

![20181220_15.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/3c176517-d93b-3e19-2d49-c28048614683.png)

**[Save]** をクリックして設定を保存します。

Bot Service の設定 ブレードの一番下にある **OAuth 接続設定** の欄に新しく作成した接続が表示されるので、クリックして開きます。
![20181220_16.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/50f5b4eb-644a-9ca4-d68e-39bc78688805.png)

**接続テスト** をクリックします。
![20181220_17.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/b5337513-63b5-04d6-1a6b-f5e6bd032231.png)

新しいブラウザーが開き、**初回のみ** アプリが要求しているアクセス許可の一覧が表示されるので、Accept(承認) をクリックします。
![20181220_18.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/0285616b-89bd-fb5f-2a50-f6d9f6d0b22c.png)

*Test Connection to (YOUR_CONNECTION_NAME) Succeeded* というページが表示されれば、無事接続ができています。
![20181220_19.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/d7364c64-1663-83de-8e71-050f5043b842.png)


# 3. Bot Framework サンプルコードを利用した認証の確認

C# または node.JS のサンプルコードに、自分で作成したアプリ設定を追加します。

## C# の場合

**AuthenticationBot.cs** の **ConnectionName** に [2.](#2-azure-bot-service-%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90) で作成した接続名を入力します。

```AuthenticationBot.cs
namespace Microsoft.BotBuilderSamples
{
 : (中略)

    public class AuthenticationBot : IBot
    {
        private const string ConnectionName = "MSGraph";
```

## node.JS の場合

**bot.js** の **CONNECTION_NAME** に 2. で作成した接続名を入力します。

```bot.js
const { ActivityTypes } = require('botbuilder');
const { ChoicePrompt, DialogSet, OAuthPrompt, WaterfallDialog } = require('botbuilder-dialogs');

 : (中略)

const CONNECTION_NAME = 'MSGraph';
```

## C# ＆ node.JS 共通

**bot-authentication.bot** に 1. で作成した **App ID** と **App Password** を入力します。

```bot-authentication.bot
{
    "name": "bot-authentication",
    "description": "",
    "services": [
      {
        "type": "endpoint",
        "appId": "YOUR_APP_ID",
        "appPassword": "YOUR_APP_PASSWORD",
        "endpoint": "http://localhost:1205/api/messages",
        "id": "1",
        "name": "development"
      }

:(後略)
```

いずれも保存して、アプリを起動します。

Bot Emulator を起動し、**[Open Bot]** をクリックして、**bot-authentication.bot** を選択します。
![20181220_21.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/4b99335d-bb0b-6109-6c37-9dadca4b787b.png)

Bot Emulator からアプリに接続し、メッセージが表示されればOKです。何か入力すると、**[Sign in]** ボタンが表示されます。
![20181220_22.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/e1b7b8af-22e7-192f-6e83-0885adb86e30.png)

クリックするとブラウザーが開くので、Office 365 アカウントでサインインを行います。
![20181220_23.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/16312251-6c68-fe8b-b9dc-010640fc4112.png)

表示されたアクセスコードを Bot Emulator に入力すると、サインインが完了です。
![20181220_24.PNG](https://qiita-image-store.s3.amazonaws.com/0/117583/c3aced7b-d84d-0295-467a-9cd68b38416c.png)