tech.guitarrapc.cóm

Technical updates

Azure SDK for .NET の認証を DefaultAzureCredential にそろえる

Azure SDK for .NET はなぜか AzureCredentialsDefaultAzureCredential という2つの認証方法があります。

今回は AzureCredentials しか受け付けない Azure SDK のクライアントに、DefaultAzureCredential で得た認証を使いたいというメモです。

tl;dr;

  • DefaultAzureCredential でとった認証はTokenを経由してAzureCredentials で利用できる
  • Token は 10分で切れるので長時間実行に使いまわすには 再度認証をとるなり工夫が必要
  • 多少の手間があってもDefaultAzureCredential のほうが認証の取り方が楽なので使っていきたい

AzureCredentials をなぜ使いたくないのか

AzureCredentials は古い Azure SDK (あるいは移行されていないSDK) でのみ利用されている (?) 気配です。AzureCredentials を使うには、個別サービスパッケージ Microsoft.Azure.Management.Xxxxx 以外にMicrosoft.Azure.Management.ResourceManager.Fluent を参照します。

例えばこんな感じで使えます。

gist.github.com

AzureCredentials は触ってみると使いにくい点がいくつかあります。

  • ローカルでの認証 (例: ServicePrincipal) や Managed Service Identity (System Assigned Identity / UserAssigned Identity) ごとにインスタンスの生成方法が異なる
  • NewtonSoft.Json 10.0.3 に依存していて脆弱性が解消されていない。1
  • 生成方法が SdkContext.AzureCredentialsFactory.FromXxxnew AzureCredentials(new XxxInformation の2つがありAPIから推測する情報が多い

Newtonsoft.Json の脆弱性 https://github.com/advisories/GHSA-5crp-9r3c-p9vr
medium.com

次に示す DefaultAzureCredential や他クラウドでの認証を考えると触りたくないと感じます。

DefaultAzureCredential でどう変わるのか

DefaultAzureCredential は新しい Azure SDK for .NET で利用が進んでいる気配で、新しいSDK やインターフェースでは DefaultAzureCredential が利用されています。(全部じゃない) DefaultAzureCredential を使うには、Azure Identity SDK を参照します。

例えばこんな感じで使えます。

gist.github.com

DefaultAzureCredential は、new DefaultAzureCredential() あるいは new DefaultAzureCredential(new DefaultAzureCredentialOptions())とインスタンスを生成するだけで動作環境から自動的に認証を取得します。例えば、環境変数、Azure環境上で Managed Service Identity (System Assigned Identity / UserAssigned Identity) 、Visual Studio、Visual Studio Code、az login など一通りカバーされており便利です。

docs.microsoft.com

AzureCredentials での開発体験を振り返ると、DefaultAzureCredential の「同じインスタンス生成で動作環境に応じた認証をいい感じに取れる」というのは、環境ごとの書き分けがいらないため書き心地が安定しており好ましく感じます。2

特に UserAssignedIdentity と System AssignedIdentity が 環境変数 AZURE_CLIENT_ID の有無で切り替わるのは、利用側で自由に調整できるので非常に都合がいいです。3

docs.microsoft.com

DefaultAzureCredential で得た認証を AzureCredentials で利用する

DefaultAzureCredentialAzureCredentials と型レベルでは互換性がないため代わりに利用できません。 しかし、DefaultAzureCredential でとった認証のトークンは、Microsoft.Rest.TokenCredentials を経由することでAzureCredentials に差すことができます。

こうすることで、認証の取り方はDefaultAzureCredential に任せつつ、AzureCredentials を必要とするクライアントを利用できます。 例えば次のように書くことができます。

gist.github.com

TokenRequestContext は 2022年現在は、https://management.azure.com/.default 固定で問題ないはずです。(Azureはちょいちょい変わるので何も信用できない)

まとめ

ちょっと Azure Database for なんとかのSDK を使って操作しようとしたら AzureCredentials で面食らったのでした。 DefaultAzureCredential は普通な使い心地でいいのですが、AzureCredentials は厳しいものがあるので今後も避けていきたいところです。


  1. Newtonsoft.Json を明示的にパッケージ参照して解消しましょう
  2. 認証の取得の書き心地という意味では、AWS SDK for .NET は AWS IAM との紐づけを含めてもっと洗練されていると感じます。なお AWS SSO の認証は全然ダメなのでよくなってほしい。
  3. 環境変数 AZURE_CLIENT_ID があれば User Assigned Identity が参照される。