Is ConfidentialClientApplication.AcquireTokenForClient().ExecuteAsync() thread safe?
Asked Answered
D

2

8

For service to service auth using a bearer token for the app (client id and secret no user context) in .net core using MSAL.NET v4 (nuget Microsoft.Identity.Client v4.3.0) is ConfidentialClientApplication.AcquireTokenForClient().ExecuteAsync() safe to use in a singleton registered service implemented like this?

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;
        }
    }

Registered with the .net core built-in DI as

services.AddSingleton<IServiceApiAuthorizer, AADConfidentialClient>();

I've seen this answer for ADAL.NET https://mcmap.net/q/1468622/-is-acquiretokenasync-thread-safe which mentions working towards thread safety for MSAL v2+ but haven't found anything confirming if this has been done.

Doris answered 23/8, 2019 at 16:1 Comment(0)
D
7

For the client credentials flow this uses it is safe to be a singleton. I eventually found this question in the GitHub issues https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1342 which was about the on behalf of flow which had this answer to one of the questions:

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.

As the implementation in this question essentially has 1 token cache I thought it would be safe but asked for confirmation anyway and this https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1342#issuecomment-525286547 was the answer:

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

Doris answered 27/8, 2019 at 19:9 Comment(0)
D
1

In MSAL.NET v2, the ConfidentialClientApplication class had numerous methods for acquiring a token and multiple overloads per method with the many optional parameters. Similar to the new fluent syntax for ConfidentialClientApplicationBuilder, it is now possible to specify required parameters in the primary AcquireToken_xxx_() method with optional parameters in follow-on method calls with a final call to ExecuteAsync().

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

The above changes were the minimal amount of code changes required to upgrade to MSAL .NET v3 or v4.

So it is safe in MSAL.NET v4. You could also refer to the v4 release.

Distinguishing answered 27/8, 2019 at 7:57 Comment(1)
Hi, there is no upgrade of MSAL versions here this is for a new code base. I've read those docs and also aka.ms/msal-net-client-credentials none of which mention thread safety. Do you have any links that specifically say if the client or token acquisition is thread safe?Doris

© 2022 - 2024 — McMap. All rights reserved.