Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] multiple_matching_tokens_detected occors when response does not include scope and AcquireTokenSilent does not include default scopes #5094

Open
hahn-kev opened this issue Jan 22, 2025 · 1 comment
Labels
needs attention Delete label after triage public-client untriaged Do not delete. Needed for Automation

Comments

@hahn-kev
Copy link

hahn-kev commented Jan 22, 2025

Library version used

4.67.2

.NET version

dotnet 9

Scenario

PublicClient - desktop app

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

After a token refresh my cache gets corrupted with 2 tokens, this means I get the dreaded multiple_matching_tokens_detected forcing me to log out the user and prompting them to login again. In my scenario I'm using a custom server using the WithOidcAuthority option. This server is using OpendIddict for it's implementaiton. After doing a fair bit of debugging I've been able to determine the following.

  1. AcquireTokenInteractive with scopes my-scope profile openid
  2. here TokenClient includes default scopes: my-scope profile openid offline_access
  3. everything goes fine, the server does return the scopes and so the token is recorded with the scopes my-scope profile openid offline_access and stored in the cache
  4. later a refresh triggers, via AcquireTokenSilent with scopes my-scope profile openid
  5. again TokenClient includes the default scopes adding the offline_access scope
  6. this time the server does not return the scopes, and then here the TokenClient sets the response scope manually, however instead of using my-scope profile openid offline_access based on the request that was executed it uses my-scope profile openid
  7. this new token with the scopes my-scope profile openid is cached, however since it doesn't match the previous token's scopes it stores both
  8. next time we try to fetch the token from the cache we run into the multiple_matching_tokens_detected error

Relevant code snippets

// sort of an example, it's hard to include a snippet for the server side. Configure the application to use a cache then the following will throw the error on the 3rd call.

_application.AcquireTokenInteractive(["my-scope"]).ExecuteAsync();
_application.AcquireTokenSilent(["my-scope"], account).WithForceRefresh(true).ExecuteAsync();
_application.AcquireTokenSilent(["my-scope"], account).ExecuteAsync();

Expected behavior

I would expect to not have the cache corrupted with 2 tokens and just replace the previous one on refresh

Identity provider

Other

Regression

No response

Solution and workarounds

I was able to work around this be ensuring that when I call AcquireTokenInteractive and AcquireTokenSilent I always include the scopes profile openid offline_access in addition to whatever I'm requesting.

I suspect this could be fixed by changing

response.Scope = _requestParams.Scope.AsSingleString();

to this:

response.Scope = scopes;

as _requestParams represents what's passed in from AcquireToken* but scopes includes the default scopes injected into every request

@hahn-kev hahn-kev added needs attention Delete label after triage untriaged Do not delete. Needed for Automation labels Jan 22, 2025
@bgavrilMS
Copy link
Member

Do I understand correctly that this occurs with an identity provider that is not related to Entra Id ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs attention Delete label after triage public-client untriaged Do not delete. Needed for Automation
Projects
None yet
Development

No branches or pull requests

2 participants