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

时间:2019-08-23 16:01:48

标签: c# .net-core asp.net-core-2.2 msal

在使用MSAL.NET v4(nuget Microsoft.Identity.Client v4.3.0)的.net核心中,使用应用程序的承载令牌(客户端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核心内置DI注册为

services.AddSingleton<IServiceApiAuthorizer, AADConfidentialClient>();

我已经看到ADAL.NET https://stackoverflow.com/a/53163274/184220的答案,该答案提到了致力于MSAL v2 +的线程安全的工作,但是还没有任何东西可以确认是否已经完成。

2 个答案:

答案 0 :(得分:0)

在MSAL.NET v2中,ConfidentialClientApplication类具有许多用于获取令牌的方法,并且每个方法具有许多可选参数,从而导致多个重载。类似于ConfidentialClientApplicationBuilder的新流利语法,现在可以在后续AcquireToken_xxx_()的后续方法调用中使用可选参数在主要ExecuteAsync()方法中指定必需参数。

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

以上更改是对upgrade to MSAL .NET v3 or v4进行的最少代码更改。

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

答案 1 :(得分:0)

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

  

每个令牌缓存应具有1个机密客户端应用程序。并且我们建议您每个会话有1个令牌缓存,因此每个会话应有1个CCA。

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

  

是的,对于客户凭证流,单例应该可以正常工作。您是在为应用程序而不是用户请求令牌。无论应用程序中有多少用户和会话,内存缓存(针对该应用程序)将只有1个访问令牌。