Skip to content

TokenAcquirer factory is not thread safe and cannot handle multiple azure regions #2765

@sammurrayms

Description

@sammurrayms

Microsoft.Identity.Web Library

Microsoft.Identity.Web

Microsoft.Identity.Web version

2.17.4

Web app

Sign-in users and call web APIs

Web API

Protected web APIs (validating tokens)

Token cache serialization

Not Applicable

Description

When calling tokenAcquirerFactory.GetTokenAcquirer from multiple thread, behavior wasn't uncertain as the underlying datastructure is a non thread safe dictionary.

Additionally, when calling tokenAcquirerFactory.GetTokenAcquirer passing differnet regions, only one tokenAcquirer is ever created and returned.

Reproduction steps

  1. Call TokenAcquirerFactory.GetTokenAcquirer passing US as the region
  2. Call TokenAcquirerFactory.GetTokenAcquirer passing EU as the region

The US TokenAcquirer is returned again instead of creating a new EU regioned TokenAcquirer.

Error message

No response

Id Web logs

No response

Relevant code snippets

public void AcquireToken_WithMultipleRegions()
        {
            var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
            _ = tokenAcquirerFactory.Build();

            ITokenAcquirer tokenAcquirerA = tokenAcquirerFactory.GetTokenAcquirer(
               authority: "https://login.microsoftonline.com/msidentitysamplestesting.onmicrosoft.com",
               clientId: "6af093f3-b445-4b7a-beae-046864468ad6",
               clientCredentials: s_clientCredentials,
               "US");

            ITokenAcquirer tokenAcquirerB = tokenAcquirerFactory.GetTokenAcquirer(
               authority: "https://login.microsoftonline.com/msidentitysamplestesting.onmicrosoft.com",
               clientId: "6af093f3-b445-4b7a-beae-046864468ad6",
               clientCredentials: s_clientCredentials,
               "EU");

            Assert.Equal(tokenAcquirerA, tokenAcquirerB);
        }

Regression

No response

Expected behavior

A new TokenAcquirer should be returned for each region:

 public void AcquireToken_WithMultipleRegions()
        {
            var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
            _ = tokenAcquirerFactory.Build();

            ITokenAcquirer tokenAcquirerA = tokenAcquirerFactory.GetTokenAcquirer(
               authority: "https://login.microsoftonline.com/msidentitysamplestesting.onmicrosoft.com",
               clientId: "6af093f3-b445-4b7a-beae-046864468ad6",
               clientCredentials: s_clientCredentials,
               "US");

            ITokenAcquirer tokenAcquirerB = tokenAcquirerFactory.GetTokenAcquirer(
               authority: "https://login.microsoftonline.com/msidentitysamplestesting.onmicrosoft.com",
               clientId: "6af093f3-b445-4b7a-beae-046864468ad6",
               clientCredentials: s_clientCredentials,
               "EU");

            Assert.NotEqual(tokenAcquirerA, tokenAcquirerB);
        }

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions