-
Notifications
You must be signed in to change notification settings - Fork 375
Description
Library version used
4.73.1
.NET version
net8-windows
Scenario
PublicClient - desktop app
Is this a new or an existing app?
The app is in production, I haven't upgraded MSAL, but started seeing this issue
Issue description and reproduction steps
The issue occurs when using non-tenanted OIDC authority (OpenIdDict in our case):
builder.WithExperimentalFeatures().WithOidcAuthority(xxx)
.
When attempting to silently acquire an access token for the same scopes as before, after it was auto-renewed at least once (before the previous token has expired), we end up in a situation where we have two valid access tokens in cache.
After researching the code, we have noticed that when creating a token cache item for non-tenanted authority, the tenantId
on the token cache item is set to an empty string:
Line 141 in f3810f5
TenantId = tenantId ?? ""; |
While in DeleteAccessTokensWithIntersectingScopes
method it looks for tokens that have tenantId
strictly equal to null
therefore not deleting the previous token which is still active for a few minutes.
microsoft-authentication-library-for-dotnet/src/client/Microsoft.Identity.Client/TokenCache.cs
Lines 140 to 141 in f3810f5
string.Equals(accessToken.TokenType ?? "", tokenType ?? "", StringComparison.OrdinalIgnoreCase) && | |
string.Equals(accessToken.TenantId, tenantId, StringComparison.OrdinalIgnoreCase) && |
The next time AcquireTokenSilent
is called for the same authority/account/scope, the following exception will be thrown, which makes sense, since there will indeed be two active tokens in the cache:
Microsoft.Identity.Client.MsalClientException
HResult=0x80131500
Message=The cache contains multiple tokens satisfying the requirements. Try to clear token cache.
Source=Microsoft.Identity.Client
StackTrace:
at Microsoft.Identity.Client.TokenCache.GetSingleToken(List`1 tokenCacheItems, AuthenticationRequestParameters requestParams)
at Microsoft.Identity.Client.TokenCache.<Microsoft-Identity-Client-ITokenCacheInternal-FindAccessTokenAsync>d__41.MoveNext()
This exception was originally thrown at this call stack:
Microsoft.Identity.Client.TokenCache.GetSingleToken(System.Collections.Generic.List<Microsoft.Identity.Client.Cache.Items.MsalAccessTokenCacheItem>, Microsoft.Identity.Client.Internal.Requests.AuthenticationRequestParameters)
Microsoft.Identity.Client.TokenCache.Microsoft.Identity.Client.ITokenCacheInternal.FindAccessTokenAsync(Microsoft.Identity.Client.Internal.Requests.AuthenticationRequestParameters)
Relevant code snippets
Expected behavior
Upon renewal of an access token for non-tenanted authority, the old access token should be removed from cache.
Identity provider
Other
Regression
No response
Solution and workarounds
No response