Azure.Identity でアクセストークンを再取得する方法を見つけることができなかったので、Azure.Identity が依存している Microsoft Authentication Library for .NET(MSAL.NET) を試してみた。
using System.Net.Http.Headers; using Microsoft.Graph; using Microsoft.Identity.Client; // Microsoft Todo のタスクとリストを CRUD するには // Tasks.ReadWrite の許可が必要。 // リフレッシュトークンを取得するためには // offline_access も必要。 var scopes = new[] { "offline_access", "Tasks.ReadWrite", }; // 一般ユーザーの Microsoft Todo にアクセスするときは // common を指定すれば良いみたい。 var tenantId = "common"; // Azure AD で登録したアプリケーションの ID (Client ID) var clientId = "YOUR_CLIENT_ID"; // Web ブラウザを表示して、 // ユーザーに Microsoft アカウントにログインし、 // アクセストークンを取得。 var pca = PublicClientApplicationBuilder.Create(clientId) .WithTenantId(tenantId) .WithRedirectUri("http://localhost") .Build(); var authResult = await pca.AcquireTokenInteractive(scopes).ExecuteAsync(); Console.WriteLine($"ExpiresOn: {authResult.ExpiresOn}"); // 内部でキャッシュされているリフレッシュトークンを使って、 // 新しいアクセストークンを取得。 var refreshResult = await pca.AcquireTokenSilent(scopes, authResult.Account.Username) .WithForceRefresh(true) .ExecuteAsync(); Console.WriteLine($"ExpiresOn: {refreshResult.ExpiresOn}"); // DelegateAuthenticationProvider を使って、 // 取得しておいたアクセストークンを Authorization ヘッダーにセットして // Microsoft Graph を呼び出せるようにする。 var authProvider = new DelegateAuthenticationProvider(request => { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", refreshResult.AccessToken); return Task.CompletedTask; }); var graphClient = new GraphServiceClient(authProvider); // リスト一覧表示 var todoLists = await graphClient.Me .Todo .Lists .Request() .GetAsync(); foreach (var todoList in todoLists) { Console.WriteLine($"既存のリスト: {todoList.DisplayName}"); } Console.ReadLine();
MSAL.NET はリフレッシュトークンを内部でキャッシュしているけど、取り出す手段は提供されていない。AcquireTokenSilent を呼び出すと、内部でキャッシュしているリフレッシュトークンを使って、アクセストークンを再取得してくれる。
.NET 6 で実行。
アクセストークンを再取得して Microsoft Graph を呼び出し、Microsoft Todo の TodoList 取得に成功した。
リフレッシュトークンのキャッシュはインメモリなので、プログラムを終了したら失われてしまう。永続化する方法を調べないといけないな。