question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Bug] AcquireTokenSilent always calls a new refresh token when .WithAuthority is set on it.

See original GitHub issue

Which Version of MSAL are you using ? MSAL 4.5.0

Platform net45, netcore

What authentication flow has the issue? AcquireTokenSilent

Other? - please describe;

Is this a new or existing app? This is a new app or experiment

Repro

public async Task<AuthenticationResult> GetAuthTokenForGraphAsync(string clientId, string cacheFileName, string cacheFilePath)
{
	IPublicClientApplication publicClientApp = PublicClientApplicationBuilder
						   .Create(clientId)
						   .Build();
						   
	StorageCreationProperties storageCacheProperty = new StorageCreationPropertiesBuilder(cacheFileName, cacheFilePath, clientId)
		.Build();

	MsalCacheHelper msalCacheHelper = await MsalCacheHelper.CreateAsync(storageCacheProperty);
	msalCacheHelper.RegisterCache(publicClientApp.UserTokenCache);
	
	List<string> scopes = new List<string> { "User.Read" };

	var accounts = await publicClientApp.GetAccountsAsync();
	try
	{
		return await publicClientApp.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
		// .WithAuthority(publicClientApp.Authority) causes MSAL to always call a new refresh token even if the token cache is in a valid state.
				.WithAuthority(publicClientApp.Authority)
				.ExecuteAsync();
	}
	catch (MsalUiRequiredException)
	{
		return await publicClientApp.AcquireTokenWithDeviceCode(scopes,
					deviceCodeResult =>
					{
						Console.WriteLine(deviceCodeResult.Message);
						return Task.FromResult(0);
					}).ExecuteAsync();
	}
}

var authenticationProvider = new DelegateAuthenticationProvider(async (request) =>
{
	string clientId = YOUR_CLIENT_ID;
	string cacheFileName = "UserCacheFileName.bin3";
	string cacheFilePath = YOUR_CACHE_FILE_PATH;
	AuthenticationResult result = await GetAuthTokenForGraphAsync(clientId, cacheFileName, cacheFilePath);
	request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", result.AccessToken);
});

GraphServiceClient graphClient = new GraphServiceClient(authenticationProvider);

// Make request. 
for (int i = 0; i < 25; i++)
{
	User me = await graphClient.Me.Request().GetAsync();
	Console.WriteLine(me.Id);
}

Expected behavior MSAL should always use a valid token from the token cache when .WithAuthority(URI) is set on publicClientApp.AcquireTokenSilent(......).

Actual behavior When .WithAuthority(URI) is set on publicClientApp.AcquireTokenSilent(......), MSAL always calls https://login.microsoftonline.com/common/oauth2/v2.0/token to get a refresh token for every call. This behavior is expensive, and the calling app occasionally gets throttled for making looping calls.

Additional context/ Logs / Screenshots Current call pattern: image

Expected call pattern: image

This issue could potentially be present in other OAuth flows besides device code flow.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jennyf19commented, Nov 4, 2019

@peombwa Included in 4.6 release

1reaction
darrelmillercommented, Oct 21, 2019

@peombwa As a workaround, we can check if the first segment of Authority is “common”, “organizations”, or “consumers” and if so, just not call WithAuthority() on AcquireTokenSilent.

Read more comments on GitHub >

github_iconTop Results From Across the Web

MSAL.NET OBO refresh token problems - oauth 2.0
Problem 2: Whenever I call MSAL's AcquireTokenSilent, I always get the error "No refresh token found in the cache." even though I got...
Read more >
Understanding MsalUiRequiredException
Access tokens expire in 1h, and AcquireTokenSilent will try to fetch a new one based on a refresh token (in OAuth2 terms, ...
Read more >
What Are Refresh Tokens and How to Use Them Securely
Refresh token rotation is a technique for getting new access tokens using refresh tokens that goes beyond silent authentication. Refresh token ...
Read more >
How to implement OAuth for Azure AD and personal ...
I'm developing a desktop app. It is already created without OAuth 2.0 we have used `Imap.UseBestLogin` ... a token. or the issue is...
Read more >
Refresh Tokens - OAuth 2.0 Simplified
If you do not get back a new refresh token, then it means your existing refresh token will continue to work when the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found