.NETでAzureのARM REST APIを叩きたい

というときのTipsみたいなもの。今回の前提条件は

  • Azure ADにアプリケーションの登録をしたくない。
  • 対話ログインOK、ただしMFAが必要。

というところです。

とりあえずの共通事項として、AADにアプリを登録したくないのであればAzure PowerShellの情報を使わせてもらおうということで、そちらの定義を書いておきます。

        private const string ARMClientID = "1950a258-227b-4e31-a9cf-717495945fc2"; // <- this is Azure PowerShell client id
        private const string AppRedirectUrl = "urn:ietf:wg:oauth:2.0:oob"; // <- this is Azure PowerShell redirect url

.NET Frameworkの場合

.NET Frameworkの場合、ADALv3で AcquireTokenAsync の parameters にプロンプトの挙動を指定できるので、PromptBehavior.Auto とかにすると自動的にサインイン用のウィンドウを出してくれます。

            var authenticationContext = new AuthenticationContext(authContextURL);
            var token = await authenticationContext.AcquireTokenAsync(
                resource: "https://management.azure.com/", 
                clientId: ARMClientID,
                redirectUri: new Uri(AppRedirectUrl), 
                parameters: new PlatformParameters(PromptBehavior.Auto));

この時、アプリケーションのクライアントIDとそのリダイレクトURLが必要なのですが、ARM REST API叩くだけであればAzure PowerShellの情報を使えばとりあえずなんとかなります。(AADにアプリ登録しなくてもいい。もちろんできるならしてもいい)

サインイン用ウィンドウではいつものプロセスが走るのでアカウントの設定に応じてMFAなどももちろんサポートします。

※GistにあげたコードはFileCache使ってますが無くてもOK

.NET Coreの場合

.NET Coreの場合、PlatformParameters クラスのコンストラクタに挙動(PromptBehavior)を指定できません。UI用ライブラリが無いからサポートしてない感じ(.NET Core 3.0でひょっとしたらサポートされるかも)
なのでデバイスコードを使ったサインインを使います。

            var authContextURL = "https://login.windows.net/common/";
            var authenticationContext = new AuthenticationContext(authContextURL);
            var deviceresult = await authenticationContext.AcquireDeviceCodeAsync("https://management.azure.com/", ARMClientID);
            Console.WriteLine(deviceresult.VerificationUrl);
            Console.WriteLine("device code: {0}", deviceresult.UserCode);
            var token  = await authenticationContext.AcquireTokenByDeviceCodeAsync(deviceresult);

デバイスコードを入力する用のURLをユーザーが開いてコードを入力する手間が必要ですが、現状プラットフォームを気にせず(.NET Coreが動作すれば)対応することができます。(ブラウザで認証するプロセスはどの端末でもいいので画面が無いデバイス上でREST API叩いたりする際の常套手段ですね)

※挙動的にはAcquireTokenByDeviceCodeAsyncはデバイスコードを使った認証が完了するまで待機します。

おまけ

FileCache(TokenCache)を実装してAuthenticationContextのコンストラクタで指定することで2回目以降のサインインを簡略化できます。FileCacheの実装はサンプルから流用しました。

参考

コメントを残す

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

WordPress.com ロゴ

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

Google フォト

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

Twitter 画像

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

Facebook の写真

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

%s と連携中