VisualStudioからAzure KeyVaultにアクセスするときにえらいハマった話
はじめに
今回の記事は下記の環境で検証を行っています。
記事を参照されるタイミングによっては画面構成や設定などが変わる可能性がありますのでご留意ください。
- Visual Studio Enterprise: 16.7.2
※以降Visual StudioはVSと記載しています
発生した問題
とあるアカウントを使用した場合、VSのConnected Serviceを使用してAzure Key Vaultにアクセスできない。
結論
16.7以降のVisualStudioからAzureに接続するための認証を行う場合、認証がうまく行かない場合があるようです。
Azureのリソースは認識できてるのに、肝心の接続のときはうまくいかない!
そんな場合はNuGetでAzure.Identity
のバージョンを1.2.2以上に上げて、下記のいずれかを行うことでうまくいくようです。
launchSettings.json
でAZURE_TENANT_ID
を指定するnew DefaultAzureCredential(new DefaultAzureCredentialOptions { VisualStudioTenantId = "<AzureのテナントID>" }))
を指定する
どえらいハマってVSアンインストールとかして悔しい感じなので、以降、解決までの試行錯誤やらの過程の話です。
ConnectedServiceでAzure KeyVaultにアクセスできなくなった
VS16.7からVisualStudioのConnectedServiceを使用した際に構成される内容が変わりました。
開発時は基本的にユーザーシークレットを使用すると思うのですがちょっと使ってみたろと思ったのがすべての始まりでした。
ひとまず、Azure KeyVaultへの接続設定をVSから行ってみます。
構成されるライブラリだけで見ると👆な感じの変更内容のようです。
Azure.Identityを使用するような変更が行われたという感じですね。
さて、これで実行を行うとエラーとなり実行ができませんでした。
正常に実行できる環境もあり、いわゆるおま環事象といった感じです。
AzureADアプリケーションを調べる
MsalServiceException: AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908.
エラー内容は上記のとおりです。指定されたAzureADアプリが存在しないようです。
なるほどー。というわけでAzureADアプリを作成し、KVのアクセスポリシーに割り当てます。
Program.csも下記のように作成したClientIdを使用するように書き換えました。
.ConfigureAppConfiguration((context, config) => { var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri")); config.AddAzureKeyVault( keyVaultEndpoint, new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = "<作成したADアプリID>" })); })
しかし結果は変わりませんでした。
別の認証が通るか試してみる
Azure SDK: What’s new in the Azure Identity August 2020 General Availability Releaseという記事でライブラリについて詳細にかかれています。
ひとまずVisualStudioの認証で失敗したけど、他の認証で成功してたらおkなのでは?と短絡に考え
Azure CLIでログイン状態にしてリトライしてみましたが結果は同じでした。
ADアプリの設定の問題かな?と思ったので正常に動作する側のAzureADアプリを見てみようと考えました。
認証フローを追う
設定を見るにも認証に使用されているAzureADのClientIDを見ないと始まりません。
そこでどのような認証が行われているのか正常に動作する環境を動かしながらFiddlerで追っかけてみました。
色々アレな情報が出てくるのでキャプチャは控えますが
ここで使用されているであろうClientIDの特定はできましたが、正常に動作する環境上でもAzureADアプリは見つかりませんでした。
で、あれば問題の根本はアプリが存在しないということはないだろうな。ということで別の線を当たることにしました。
テナントを指定する
先程記載したブログの記事でテナントの指定の仕方を記載した項目があります
authenticate-to-a-specific-tenant
僕のアカウントはAD/AD B2C含め複数のテナントに所属しており、且つオーナーとなっているテナントも複数あるのでHomeテナントを誤認したのかもしれません。
まずは👆記事に記載されている内容で解決できるか確認してみます。
Azure.Identityの1.1.1のDefaultAzureCredentialOptions
にVisualStudioTenantId
は存在しないので
Azure.Identityの1.2.2に上げる必要があります。
.ConfigureAppConfiguration((context, config) => { var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri")); config.AddAzureKeyVault( keyVaultEndpoint, new DefaultAzureCredential(new DefaultAzureCredentialOptions { VisualStudioTenantId = "<Azure Tenant Id>" })); })
これでやっと動作するようになりました。
その後に試したこと
DefaultAzureCredentialOptions
を指定せずに解決できないか試しました。
VisualStudioのAzureサービス認証のアカウント絞り込み
VisualStudioの認証で使用しているアカウントに紐づくテナントを絞り込めば同じ状態になるかな?
と思い試してみましたが結果は変わりませんでした。
lauch.settings.json
でAZURE_TENANT_ID
を指定する
この方法はうまくいきました。実行ソース側をいじるのが嫌であればこちらを指定するほうが良い感じですね。
おわりに
認証まわりで沼ると解決まで時間がかかるので
ローカルでの開発時はユーザーシークレットがド安定ですね😏