ConfidentialClientApplication.AcquireTokenForClient().ExecuteAsync() 线程安全吗?

Is ConfidentialClientApplication.AcquireTokenForClient().ExecuteAsync() thread safe?

对于使用 MSAL.NET v4 (nuget Microsoft.Identity.Client v4.3.0) 的应用程序的持有者令牌(客户端 ID 和秘密无用户上下文)的服务到服务身份验证是 ConfidentialClientApplication.AcquireTokenForClient().ExecuteAsync() 在这样实现的单例注册服务中使用安全吗?

public class AADConfidentialClient : IServiceApiAuthorizer
    {
        private readonly IConfidentialClientApplication _confidentialClient;
        public AADConfidentialClient(IOptions<ConfidentialClientApplicationOptions> options)
        {
            _confidentialClient = ConfidentialClientApplicationBuilder
                     .CreateWithApplicationOptions(options.Value)
                     .Build();
        }

        public async Task<string> GetTokenAsync(IReadOnlyCollection<string> scopes)
        {
            var result = await _confidentialClient.AcquireTokenForClient(scopes).ExecuteAsync();

            return result.AccessToken;
        }
    }

向.net core 内置 DI 注册为

services.AddSingleton<IServiceApiAuthorizer, AADConfidentialClient>();

我看到了 ADAL.NET 的这个答案,其中提到为 MSAL v2+ 的线程安全而努力,但没有找到任何确认是否已经完成的东西。

在 MSAL.NET v2 中,ConfidentialClientApplication class 有许多获取令牌的方法和每个方法的多个重载以及许多可选参数。与 ConfidentialClientApplicationBuilder 的新流畅语法类似,现在可以在主要 AcquireToken_xxx_() 方法中指定必需参数,并在最终调用 ExecuteAsync() 的后续方法调用中指定可选参数。

authResult = await _clientApplication.AcquireTokenForClient(_scopes).ExecuteAsync();

以上更改是 upgrade to MSAL .NET v3 or v4 所需的最少代码更改。

因此在 MSAL.NET v4 中是安全的。您也可以参考 v4 release.

对于client credentials flow这个使用单例是安全的。我最终在 GitHub 问题 https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1342 中找到了这个问题,它是关于 on behalf of flow 的,其中有一个问题的答案:

You should have 1 Confidential Client Application for each token cache. And we recommend that you have 1 token cache per session, so there should be 1 CCA per session.

由于这个问题中的实现基本上有 1 个令牌缓存,我认为它是安全的,但无论如何都要求确认,这个 https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1342#issuecomment-525286547 就是答案:

yes, for Client Credentials flow a singleton should work fine. You are requesting tokens for an application, not for a user. There will only be 1 access token in the in-memory cache (for the app), irrespective of how many users and sessions there are