Azure, Bot, 開発

Bot に Azure AD 認証/認可を組み込む

こんにちは! SecretaryBot開発チームのマサです!今回はBotにAzure ADの認証/認可機能を埋め込む方法を解説します。

Botをある程度作りこんでくると、外部のAPIと連携したくなることがあると思います。僕らの場合にはOffice 365のデータを読み書きしたかったので、Microsoft Graph APIと連携したくなりました。Microsoft Graph APIをCallするためにはAzure ADでの認証/認可が必須なので、この記事ではBotにAzure ADの認証/認可を実装する方法を紹介します。

実際にAzure ADでの認証/認可を行いMicrosoft Graph APIを呼び出すためには「OAuthでの認証/認可実装と、Access Tokenの保持/更新機能の実装」が必要になります。方法は大まかにいうと以下2つです。

  • 自分で書く: OAuth用のControllerを作って、認証/認可が終わったらState Serviceなどのキャッシュ機構にAccess Tokenを保持する。Microsoft Graph API Call時に401が帰ってきたらRefresh Tokenを使って都度更新する(実装案の一例)。
  • ライブラリを使う

もともとは僕は自分で認証/認可関連の実装をしていたのですが、プロジェクトを迅速に進めるうえで、この部分の実装負荷は減らしたいなぁと思っていました。そんな時出張先で知り合ったMatから「オレの作ったライブラリあるから使ってみてよ。なんか問題とか良いアイディアあったらプルリクちょうだい」とAuthBotのライブラリを紹介されました。

そして、今はこれを使っています。ちなみに、Bot Frameworkの公式ライブラリではない点については留意したうえで、公開されているコードを読んで、自分のプロジェクトでの活用が問題ないかを確認する必要があります(オープンソース系あるある)。

前提条件

以下の環境の用意が必要になります。

  • Azure AD (Azure テナントが必要です。なければ無償評価版を使えます。)
  • Office 365 (Botを認証したいだけなら不要。Microsoft Graph APIの認可までしたいなら必須。開発用のOffice 365テナントはDeveloper Programに参加すると無償で作れます。)

準備

記事でも解説しますが、大まかな作り方は動画(25分くらい)を見ておくといいかなと思います。

1.Azure ADにアプリケーション設定する

OAuthを利用するにはClient ID (アプリケーションID)だったり、リダイレクト先のURLが必要になります。「普段使っているOffice 365のアカウントで認証するBotを作りたい」という時には、アプリケーションごとのClient ID発行やリダイレクトURLの設定はAzure AD で行います。

  1. Azure Portal にアクセスします
  2. 左下の[その他のサービス>]をクリックします
  3. [フィルター]テキストボックスに “Azure”とか入力して絞り込むと[Azure Active Directory]というやつが出てきます。(星マークをクリックしてお気に入りにしてもいいかもしれないです。)クリックします。
  4. Azure AD用のブレードが出てくるのですが、[アプリの登録]をクリックします。
  5. [アプリの登録]ブレードが表示されます。
  6. [追加]をクリックします。
  7. [名前]に好きな、かつ、ユニークな名前を追加しましょう。
  8. [アプリケーションの種類]は”Webアプリ/API”のままで大丈夫です。
  9. [サインオンURL]には今は適当なURLを入れてください。https://localhost.com とかで大丈夫です。
  10. しばらくすると[アプリの登録]ブレード内のアプリ一覧に先ほど追加したアプリが表示されるようになりますのでクリックしましょう。
  11. アプリケーション用のブレードが表示されるので、[アプリケーションID]の中の文字列をメモしてください。

次にキーの取得もします。

  1. [設定]ブレード内で[キー]をクリックします。[キー]ブレードが表示されます。
  2. [説明]テキストボックスは後からわかりやすい説明を入力し、[有効期限]で好きな有効期限を選んでください。その後[保存]ボタンをクリックすると、[値]列のところにキーが表示されます。ブレードを閉じると2度と表示されなくなるので、きちんとメモしておきましょう。
  3. [キー]ブレードを閉じます。(どうでもいいですが、キーブレードってキングダムハーツを思い出しますね^ ^)

最後にリダイレクトURLを指定します。

  1. [設定]ブレードで[応答URL]をクリックします。
  2. https://localhost:44318/api/OAuthCallback を追加して、[保存]ボタンをクリックしてください。この値は後程作りこむアプリ側と連携させています。production環境のWebサーバーが例えば、 https://masota.com の場合には https://masota.com/api/OAuthCallback も追加しておいてください。
  3. [応答URL]ブレードを閉じましょう。

2. アプリケーションをマルチテナント対応にする

Azure ADにはマルチテナント対応のための設定があります。

この設定をしないと、デフォルトでシングルテナントアプリになるのですが、シングルテナントアプリは「このアプリを登録したADのテナントにいるユーザー」のみがログインできます。自社向けカスタムBotにはいいかもしれないです。

一方で、マルチテナント対応すると、どのテナントのユーザーもログインできます。ボットをどこかに公開して多くの人に触ってもらうには必須の設定ですね!

ちなみに、テナントの管理者が厳しい設定していると、「このアプリだとログインできないよ」という感じのエラーメッセージが表示されることがありますので注意してください。開発用テナントではうまく動作するのに、自分の会社では使えない!というときはIT管理部門と要調整です。

設定手順は以下のような感じです(先ほどの手順の続きです)

  1. [プロパティ]をクリック
  2. [プロパティ]ブレードが表示されます。
  3. [マルチテナント]が”いいえ”になっているので、”はい”にします。画面上のほうの[保存]ボタンをクリックしましょう。成功したという通知が表示されれば設定完了です。[プロパティ]ブレードを閉じましょう。

3. Microsoft Graph APIを使うための設定をする

次は、Microsoft Graph API を利用するための設定をします。

  1. [必要なアクセス許可]をクリックします。[必要なアクセス許可]ブレードが開きます。
  2. [API]列を見ると”Windows Azure Active Directory”というAPIがすでに追加されています。不要なので削除しましょう。API名をクリックすると[アクセスの有効化]ブレードが表示されるので、[削除]ボタンをクリックして削除を始めます。
  3. 削除完了後、[必要なアクセス許可]ブレードで[追加]ボタンをクリックしましょう。
  4. [APIアクセスの追加]ブレードが表示されるので、[APIを選択します]をクリックして[APIを選択します]ブレードを表示しましょう。
  5. “Microsoft Graph”を選択し、[選択]ボタンをクリックします。すると、[アクセスの有効化]ブレードに切り替わります。ここで必要なアクセス許可を選択することになります。ちなみに、[管理者権限が必要]列が”はい”になっているものは、Office 365テナント管理者の許可をもらわないといけないので、”いいえ”のものを選択したほうが導入しやすいとは思います。
  6. “Sign in and read user profile”を選択して、[選択]ボタンをクリックします。そして、[完了]ボタンを押して設定を終わらせましょう。無事成功すると[必要なアクセス許可]ブレードに戻り、”Microsoft Graph”が追加されます。

AuthBotの組み込み

それでは、Botに認証機能を組み込んでいきましょう。例としてMultiDialogSampleに埋め込んでみます。ちなみに、Matのページを見ると「このサンプルを参考に実装して」とあります。

こちらに完成版のコードを置いておきますが、この記事では重要なポイントを解説しておきます。

なお、AuthBotライブラリはBot Builderライブラリがアップデート後に最新版を作っているようなので、AuthBotのリリース日のほうが新しくなるようにバージョンの調整をしてください。(最新のBot Builderのほうがリリース日が新しい場合、500 Internal Server Errorとなることがあります。)

1. Nugetからライブラリを取得する

  1. Visual Studio のソリューション エクスプローラーでプロジェクト”MultiDialogSample”を右クリックした後で[Nuget Package]の管理をクリックしましょう。
  2. [Restore]というメニューが表示された場合には、クリックしましょう。必須のパッケージを自動的に読み込んでくれます。
  3. [プレリリースを含める]チェックボックスを”ON”にしたうえで、[参照]を選択します。その後検索ボックスで”AuthBot”と入力し、検索しましょう。
  4. [Install]ボタンをクリックしてインストールします。ライブラリの依存関係や使用許諾に関するダイアログなどが表示されますが、問題なければ[OK]をクリックして進めてください。これでAuthBotライブラリのインストールは完了です。楽!Nuget最高。

2.Web.configを編集する(Azure AD で取得したIDやキーの埋め込み)

次に、web.configに資格情報などを書き込んでいきましょう。ActiveDirectory.ClientIdvalueにAzure ADで取得したアプリケーションIDを、ActiveDirectory.ClientSecretvalueにAzure ADで取得したキーを入力します。

なお、ResourceIdはOAuthで認可するサービスを指していて、今回はMicrosoft Graph APIを呼ぶのでhttps://graph.microsoft.comを指定しています。EndpointUrlはMatのライブラリ内では認証認可のためのAzure ADの画面を出すエンドポイントを指しており、https://login.microsoftonline.comを指定しています。Tenantにはマルチテナント向けのアプリなのでcommonとしていますが、シングルテナントアプリの場合にはmasota.comのようにドメイン名を指定します。RedirectUrlにはOAuth認証後にリダイレクトされる先のURLを指定します。僕のサンプルはローカルデバッグ時にhttps://localhost:44318/を利用しているので、https://localhost:44318/api/OAuthCallbackのようにしています。/api/OAuthCallbackはAuthBotライブラリで必須のエンドポイントです。Production環境に展開したいときはhttps://masota.com/api/OAuthCallbackのように変更してください。

ライブラリがカプセル化してくれているOAuthの通信を理解したい方は、松崎さんのこのブログを見てみてください。しっかり理解したい場合には、Postmanや Fiddlerを使って生のHTTP Request/Responseをいじってみることをお勧めします。

<configuration>
 <appSettings>
 <!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
 <add key="BotId" value="YourBotId" />
 <add key="MicrosoftAppId" value="" />
 <add key="MicrosoftAppPassword" value="" />

 <!-- AAD Auth v1 settings -->
 <add key="ActiveDirectory.Mode" value="v1" />
 <add key="ActiveDirectory.ResourceId" value="https://graph.microsoft.com/" />
 <add key="ActiveDirectory.EndpointUrl" value="https://login.microsoftonline.com" />
 <add key="ActiveDirectory.Tenant" value="common" />
 <add key="ActiveDirectory.ClientId" value="Insert your own Client ID" />
 <add key="ActiveDirectory.ClientSecret" value="Insert your own Key" />
 <add key="ActiveDirectory.RedirectUrl" value="https://localhost:44318/api/OAuthCallback" />
 </appSettings>
...
</configuration>

3.Global.asax.csを編集する

Global.asax.csを編集し、web.configに埋め込んだ資格情報をアプリケーション起動時に読み込むようにしておきます。

using System.Web.Http;
using System.Configuration;

namespace MultiDialogSample
{
 public class WebApiApplication : System.Web.HttpApplication
 {
     protected void Application_Start()
     {
     GlobalConfiguration.Configure(WebApiConfig.Register);

     AuthBot.Models.AuthSettings.Mode = ConfigurationManager.AppSettings["ActiveDirectory.Mode"];
     AuthBot.Models.AuthSettings.EndpointUrl = ConfigurationManager.AppSettings["ActiveDirectory.EndpointUrl"];
     AuthBot.Models.AuthSettings.Tenant = ConfigurationManager.AppSettings["ActiveDirectory.Tenant"];
     AuthBot.Models.AuthSettings.RedirectUrl = ConfigurationManager.AppSettings["ActiveDirectory.RedirectUrl"];
     AuthBot.Models.AuthSettings.ClientId = ConfigurationManager.AppSettings["ActiveDirectory.ClientId"];
     AuthBot.Models.AuthSettings.ClientSecret = ConfigurationManager.AppSettings["ActiveDirectory.ClientSecret"];
     }
 }
}

4.RootDialog.csを編集する

下記のようにログイン済みかどうかを判定するロジックと、未ログインであればログイン用のDialogに飛ばすような処理を書きます。

private async Task MessageReceiveAsync (IDialogContext context, IAwaitable<IMessageActivity> result)
{
  var reply = await result;
  string accessToken = await context.GetAccessToken(ConfigurationManager.AppSettings["ActiveDirectory.ClientId"]);
  //Check login status
  if (string.IsNullOrEmpty(accessToken))
  {
    //Forward context to AzureAuthDialog for login
    await context.Forward(new AzureAuthDialog(ConfigurationManager.AppSettings["ActiveDirectory.ClientId"]), this.ResumeAfterAuth, reply, CancellationToken.None);
  }
  else
  {
    await ShowMainmenu(context);
  }
}

こうすると、下記のような動きになります。

[Authentication Required]をクリックすると、下の左ような画面になります。Azure ADにログインすると、右側のような画面になります。[承諾]をクリックしましょう。

“Almost done! Please copy this number and paste it back to your chat so your authentication can complete:<数字>”というのが表示されるので、<数字>部分をBotに入力してください。入力後、RootDialogで設計したメニューが表示されるようになります。

これで、BotがAzure AD 認証/認可をできるようになりました。ログアウトなども実装したい場合には、Matのサンプルを確認してみてください。

次回はA’がMicrosoft Graph APIを呼び出すための実装を紹介しますのでお楽しみに!

補足

“/deleteprofile”と入力すると、Conversation Stack, State Serviceをリセットできます。そのため、デバッグ時にログイン状態を解除したいときにはこのコマンドを使ってみてください。

下記のような設定をして、ASP.NET アプリケーションでSSL使うようにしています。

参考情報

  • もしAzure ADを使った開発をもっと深堀したかったら、このサイトを参考にするとよいと思います。
  • Azure AD認証やMicrosoft Graph APIの概要を知りたいときには、僕のスライドを見てみてください。
  • Azure ADを使ったOAuth Client開発は松崎さんが一番詳しいと思います。詳細を知りたい方は松崎さんのこのブログを参照してください。
  • Bot FrameworkプロジェクトのベースになっているASP.NET の詳細はこちらから。Web API の項目を参考にするとよいと思います。
広告

1 thought on “Bot に Azure AD 認証/認可を組み込む”

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中