はじめに
最近Form Recognizerをよく使っており、アクセスする際は認証のためのキーを利用しています。このキーを管理するのがちょっと面倒だなと思ったので、キーを使わずに認証する方法があるのではないかと思い調査したところ、マネージドIDを使えば実現できそうでした。
今回は実現方法を調べたので手順をメモとして残しておきます。
前提
Form Recognizerの.NET SDKの基本的な利用方法を理解していること
Azure App ServiceでホストしているアプリケーションからForm Recognizerにアクセスする場合を想定
環境
Azure.AI.FormRecognizer 4.0.0 (.NET SDK)
手順
Azureリソースの設定
まずはApp ServiceのマネージドIDを有効にします。
左側のメニューからID
を選択します(①)。今回はシステム割り当て済み
の方を利用するので選択されていることを確認し(②)、状態をオンにします(③)。App Service側の設定はこれで完了です。
次にForm Recognizerについてです。まずリソースの作成はAzureポータルからではなく、Azure Cloud Shellから行う必要があります。これはカスタムサブドメインの設定が必要なためです。Azureポータルから作成した場合カスタムサブドメインは設定できません。また、作成後にカスタムサブドメインの設定もできないようです。
実行するスクリプトは以下のようになります。
New-AzCognitiveServicesAccount -ResourceGroupName [RESOURCE_GROUP_NAME] -name [ACCOUNT_NAME] -Type [ACCOUNT_TYPE] -SkuName [SUBSCRIPTION_TYPE] -Location [REGION] -CustomSubdomainName [UNIQUE_SUBDOMAIN]
パラメータに関しては以下のように設定します。
・[RESOURCE_GROUP_NAME] →リソースグループの名前
・[ACCOUNT_NAME] →リソース名
・[ACCOUNT_TYPE] →Cognitive Serviceは複数のサービスが含まれており、どのサービスを利用するかここで指定します。サービス一覧はAzure Cloud ShellのGet-AzCognitiveServicesAccountType
というコマンドで取得できます。
今回はFormRecognizer
と指定します。
・[SUBSCRIPTION_TYPE] →価格レベルを指定します。例えば無料プランの場合はF0
、有料プランの場合はS0
です。今回はS0
にします。
※無料プランで試したところ、App Serviceに配置したアプリからForm Recognizerにアクセスするときにエラーになりました 今回の方法だと有料プランにする必要があるようです
・[REGION] →リージョンの設定です。例えば東日本の場合はjapaneast
です。
・[UNIQUE_SUBDOMAIN] →任意のサブドメインを指定します。ここに設定したものがエンドポイントに使われます。
New-AzCognitiveServicesAccount
のパラメータの使い方については以下のドキュメントが参考になります。
リソースを作成したら、次はApp Serviceにロールを与えます。
Azure Portalから作成したForm Recognizerのリソースのページに移動し、アクセス制御(IAM)
→追加
→ロール
の割り当てという順番でクリックします。
次の画面ではCognitive Services ユーザー
を選択して次へ
をクリックします。
メンバーの指定を行います。
①マネージドID
を選択
②メンバーを選択する
をクリック
③右側に画面が表示されるので先ほどマネージドIDを割り当てたApp Serviceを選択し、選択
ボタンを押します。
最後にレビューと割り当て
を押します。これでApp Serviceにロールを割り当てることができました。
以上でAzureのリソース側の設定は完了です。
コードを書く際のポイント
ソースコード側で重要なのがDefaultAzureCredential
というクラスです。これを利用するとアプリケーションを実行する環境によって認証方法が変わります。 具体的には以下の順番で認証を試みます。
① Environment
② Managed Identity
③ Visual Studio
④ Visual Studio Code
⑤ Azure CLI
⑥ Azure PowerShell
⑦ Interactive browser
今回の場合は以下のような流れになります。
①こちらはプログラム側で環境変数の値を探しに行きます。今回の場合は環境変数を設定しないのでこれは利用されません。
②今回はマネージドIDを利用するのでこの方法が採用されます。
※DefaultAzureCredentialについては私も理解しきれていない部分があるので、正確な情報は以下のドキュメントをご確認ください。
このクラスを使ってキーを利用する部分を書き換えます。
string endpoint = "<Form Recognizerのエンドポイント>"; //分析するためのクライアントを作成 var client = new DocumentAnalysisClient(new Uri(endpoint), new DefaultAzureCredential());
参考までにキーを利用する場合を掲載します。
string endpoint = "<Form Recognizerのエンドポイント>"; string apiKey = "<Form Recognizerのキー>"; var credential = new AzureKeyCredential(apiKey); //分析するためのクライアントを作成 var client = new DocumentAnalysisClient(new Uri(endpoint), credential);
ソースコードを比較すると、前者はキーを利用していないことが分かると思います。
Azureにデプロイする
最後にAzureにデプロイしてアプリケーションを実行すると問題なく動作することを確認できます。
最後に
今回はマネージドIDを利用してForm Recognizerを利用する方法について書きましたが、この方法は他のAzureサービスでも利用できます。私が試したものだと、「AppServiceからAzure Communication Servicesにアクセスする」という場合でも同様な方法で認証することができました。
調べてみると奥深そうな領域だと思ったので、今後もいろいろと調査したいと思いました。(DefaultAzureCredentialの使い方や、ローカルでも認証するようにできないか?など)