ChatGPTのプラグイン作成方法については、前回のブログに記載しました。
https://blog.jbs.co.jp/entry/2023/06/08/121455
今回は、ChatGPTのプラグインにAzure AD認証機能を実装して、Azure Web AppsのようなPublicのWebサーバーに展開する方法について調べてみました。
システム構成イメージ
システムの構成イメージは下記になります。
ChatGPTのプラグイン実装だけを考慮すればAzure Web Appsに対するユーザーのAzure AD認証は必須ではありません。
ただ、Publicにデプロイした場合、不特定多数のユーザーに無制限に権限を与えるわけにもいかないので、Azure AD認証・認可されたユーザーのみにプラグインが利用できるようにAzure ADによる認証・認可を実装しています。
図に記載されている通り、ChatGPTはAzure AD認証を直接サポートしています。
プラグインの設定ファイル(ai-plugin.json)にAzure AD認証の詳細を記述することで、ChatGPTはAzure ADを通じて認証を行います。
認証機能の実装方法については、下記のサイトを参考にしました。
作業概要
ChatGPTのプラグインを自作し、それにAzure ADの認証機能を追加する流れは下記です。
1.Blazor Serverアプリケーションの作成
Visual Studioを使用してBlazor Serverアプリケーションを作成します。
2.Azure Web Appsへのデプロイ
作成したアプリケーションをAzure Web Appsにデプロイします。
3.Program.csのCORS設定の修正
Program.csのCORS設定を修正します。
これにより、異なるオリジンからのリクエストを許可します。
4.ai-plugin.jsonの修正
ai-plugin.jsonを修正し、APIやロゴのURL、auth設定を追記します。
これにより、プラグインの基本情報と認証方法が定義されます。
5.Azure Web Appsに再デプロイ
上記の変更を反映させるために、アプリケーションを再デプロイします。
6.ChatGPT Pluginsでの読み込み
ChatGPT PluginsでデプロイしたURLを指定してプラグインを読み込みます。
7.クライアントIDとシークレットの入力
Azure ADから取得したクライアントIDとシークレットを入力します。
8.OpenAIのIDの取得と追記
OpenAIのIDが取得できたら、それをai-plugin.jsonのverification_tokensに追記します。
9.Azure Web Appsに再デプロイ
ai-plugin.jsonをVisual Studioから再デプロイします。
10.別ユーザーでのChatGPT Pluginの読み込み
上記の認証が通ったら、別ユーザーでChatGPT Pluginを読み込みます。
Azure AD認証が失敗した場合、Azure ADアプリにリダイレクトURIを追記します。
11.再度の読み込みと認証
再度読み込みを実施し、認証が通れば成功です。
作業手順
Visual StudioでBlazor Serverアプリを作成
- Visual Studio 2022を使用してBlazor Serverアプリを作成
作業内容は概ね下記ブログに掲載した内容と同じです。 下記ブログの作業手順を参照して下さい。
blog.jbs.co.jp .NETのバージョンは7を指定して下さい。
ブログで紹介しているMicrosoft.AspNetCore.OpenApiが.NET 7以前には対応していません。 今回はPublicのWeb Appsにデプロイするので、下記に記載する追加作業が必要です。 - Visual Studioで認証の種類を設定
Azure AD認証を行う為、Microsoft ID プラットフォームを選択します。
フレームワークは、今回は.NET 7を選択します。 - Azure ADアプリケーションを新規作成
画面右側の新規作成ボタンでAzure ADアプリケーションを新規に作成できます。
Azure ADアプリケーションを作成済みであれば、所有しているアプリケーション欄に表示されるAzure ADアプリケーションを選択してください。 - Microsoft ID プラットフォームの構成を確認
Microsoft Graphや別のAPIへのアクセスは今回は不要なので、チェックしません。 - Visual StudioでMicrosoft IDを確認
接続されましたと表示されていれば、Azure ADアプリケーションは作成できています。
Azure Web Appsをデプロイ
- デバッグ実行してAzure AD認証機能を確認
デプロイする前に、Azure AD認証が設定できているか確認します。
画面右上にログインユーザー名やLog Outボタンが表示されていれば、Azure AD認証は設定できています。 - Azure PortalでWeb Appsを作成
ランタイムスタックは、上記までに作成したBlazor Serverアプリケーションと同じ.NET 7を選択します。
オペレーティングシステムはWindowsを使用しました。
Azure Portalで、Web Appsがデプロイされたことを確認します。 - Azure Web Appsの環境変数を設定
Visual Studioで作成したアプリケーションのappsettings.jsonに記載されている内容を、Web Appsの環境変数に設定します。
Web Appsの環境変数の設定が完了したら、appsettings.jsonに記載されているAzure ADについての情報は削除して下さい。(削除しないままデプロイするのは、セキュリティ上の問題があります。) - Visual StudioからWeb Appsをデプロイ
ソリューション名を右クリックして、発行を選択します。
- 発行プロファイルの追加を選択
Azureを選択し、次へボタンを押します。
- Azure App Serviceを選択
Windowsを選択し、次へボタンを押します。 - デプロイ先のWeb Appsを選択
Azure Portalで作成したWeb Appsを選択し、次へボタンを押します。 - API Managementの設定
今回は不要なので、左下にある「この手順をスキップする」をチェックして完了ボタンを押します。 - Web Appsを発行
発行ボタンを押して、Web Appsにデプロイします。 - 認証エラーの表示を確認
Azure ADアプリケーションにredirect URIを設定していないので、エラーが表示されます。
表示されているsignin-oidcのリンクをコピーします。 - Azure ADアプリケーションにリンクを設定
リダイレクトURIに上記のsignin-oidcのリンクを追加します。 - アプリケーションIDの確認とクライアントシークレットを作成
この後の作業で使用するので、アプリケーションIDの確認とクライアントシークレットの作成を行います。
クライアントシークレットの値は保存されてしまうと後から確認できないので、保存する前にメモ帳などにコピーして下さい。(取り扱いにはご注意下さい)
再度、デプロイしたWeb Appsのリンクをクリックしてログインできれば問題ありません。
Program.csを修正
- Web AppsのURLを追記
今回はWeb Appsを使用するので、CORSにWeb AppsのURLを追記します。 - .well-known配下のファイルをAzure AD認証から除外
ai-plugin.jsonとfavicon.pngファイルは、Azure AD認証が必須の状態だと、ChatGPT側でマニフェストファイルとして読み込むことができません。(後述のChatGPTでのマニフェストファイル読み込みに必要)
その為、下記の設定を追加してai-plugin.jsonとfavicon.pngをAzure AD認証がなくてもアクセス可能にします。
また、swagger.yamlについてもChatGPT側で読み込むことができないので、Azure AD認証がなくてもアクセス可能にします。
app.UseRouting(); app.MapGet("/.well-known/ai-plugin.json", async context => { var fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), ".well-known")); var fileInfo = fileProvider.GetFileInfo("ai-plugin.json"); if (fileInfo.Exists) { context.Response.ContentType = "application/json"; await context.Response.SendFileAsync(fileInfo); } else { context.Response.StatusCode = 404; } }).WithMetadata(new AllowAnonymousAttribute()); app.MapGet("/.well-known/favicon.png", async context => { var fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), ".well-known")); var fileInfo = fileProvider.GetFileInfo("favicon.png"); if (fileInfo.Exists) { context.Response.ContentType = "image/png"; await context.Response.SendFileAsync(fileInfo); } else { context.Response.StatusCode = 404; } }).WithMetadata(new AllowAnonymousAttribute()); app.MapGet("/swagger/v1/swagger.yaml", async context => { var fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "swagger/v1")); var fileInfo = fileProvider.GetFileInfo("swagger.yaml"); if (fileInfo.Exists) { context.Response.ContentType = "text/yaml"; await context.Response.SendFileAsync(fileInfo); } else { context.Response.StatusCode = 404; } }).WithMetadata(new AllowAnonymousAttribute()); app.UseAuthentication(); app.UseAuthorization();
ai-plugin.jsonを修正
- 接続先の情報を追記
Azure Web AppsのURLとAzure ADアプリケーションのテナントIDを追記します。
Azure Web AppsのURLとAzure ADアプリケーションのテナントIDは、Azure Portalで確認して下さい。
{ "schema_version": "v1", "name_for_human": "Connect to Cognitive Search", "name_for_model": "blazoracs", "description_for_human": "Plugin for conducting searches on Azure Cognitive Search", "description_for_model": "Plugin for conducting searches on Azure Cognitive Search", "auth": { "type": "oauth", "client_url": "https://login.microsoftonline.com/Azure ADアプリケーションのテナントID/oauth2/v2.0/authorize", "scope": "https://graph.microsoft.com/.default", "authorization_url": "https://login.microsoftonline.com/Azure ADアプリケーションのテナントID/oauth2/v2.0/token", "authorization_content_type": "application/x-www-form-urlencoded", "verification_tokens": { "openai": "OpenAIから取得するtokensを設定する(後述)" } }, "api": { "type": "openapi", "url": "https://Azure Web AppsのURL.azurewebsites.net/swagger/v1/swagger.yaml", "is_user_authenticated": false }, "logo_url": "https://Azure Web AppsのURL.azurewebsites.net/.well-known/favicon.png", "contact_email": "contact@email.com", "legal_info_url": "http://example.com/legal" }
Web Appsに再デプロイ
- Web Appsの動作確認
発行ボタンを押して、Web Appsに再度デプロイして動作を確認します。
.well-knownフォルダ配下のファイルは、デフォルトではWeb Apps側にデプロイされないようです。
デプロイしてもhttps://AzureWebAppsのURL.azurewebsites.net/.well-known/ai-plugin.json
やfavicon.pngにアクセスできない場合は、ファイル名を右クリックして発行して下さい。
ChatGPT Pluginsで読み込み
- Develop your own pluginを選択
前回のブログに掲載しましたが、今回もDevelop your own pluginを選択してプラグインを設定します。
- Web AppsのURLをDomainに記載
前回はlocalhostでしたが、今回は作成したWeb AppsのURLを記載します。 - Azure ADアプリケーションのアプリケーションIDとクライアントシークレットを登録
上段にアプリケーションID、下段にクライアントシークレットを登録してNextボタンを押します。 - OpenAIからtokenを受領
OpenAIからtokenが発行されるので、この値をai-plugin.jsonに記載します。 - ai-plugin.jsonに記載
ai-plugin.jsonのopenaiの箇所に、発行されたtokenを記載します。
ai-plugin.jsonを更新したら、発行してクラウドに再度デプロイします。
もう一度、この画面に戻って、Verify tokensボタンを押します。
このReady to installの画面が表示されれば、プラグインの登録はできています。
Install laterを選択します。(Install for meを選択しても問題ありません)
Web Appsのプラグインが使用できる事を確認
- Plugin storeの画面を表示
Install an unverified pluginを選択して、Web Appsで作成したプラグインをインストールします。 - Web AppsのURLを登録
Web AppsのURLを記載して、Find pluginボタンを押します。
- OpenAIの注意文を確認
OpenAIからの注意文が表示されます。
問題なければContinueボタンを押します。
- ログイン画面の表示を確認
プラグインを利用する為のログイン画面が表示されます。
Log in with Connect to Cognitive Searchボタンを押します。
- サインインのエラー画面を確認
サインインエラーが表示されます。
表示されるredirect URIをAzure ADアプリケーションに登録します。
- Azure ADアプリケーションにリンクを設定
リダイレクトURIに上記のエラーで表示されたcallbackのリンクを追加します。
- 再度ログインを実行
ログイン画面が表示されます。
- プラグインの表示を確認
ログインに成功し、プラグインが表示されれば作業完了です。
まとめ
私の進め方に問題があったのか、プラグインの登録は結構面倒な作業でした。
.well-knownフォルダがデフォルトではデプロイされなかったり、Azure AD認証でなんでも認証設定してしまうとai-plugin.jsonをChatGTP側から参照できなかったりと、いろいろハマりました。
.well-knownフォルダについては、Visual Studioの.csprojを編集すればデプロイ対象にすることもできると思います。
ai-plugin.jsonについては、公開用のWebサーバーを別途作成して管理する方法もあると思いました。
プラグインは初期登録さえ行えば、後はURLの登録とログインだけで利用できるので、利用するユーザーにはそんなに負担はかからないと思います。
プラグインをPublic用とPrivate用のどちらでも作成できる方法を学んでおけば、Microsoft 365 CopilotやSemantic Kernelを活用できるので今後も注力していきます。