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.

ID token is only refreshed when Access token is expired

See original GitHub issue

Logs and network traces MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:10.83] Found 1 cache accounts and 0 broker accounts MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:10.83] Returning 1 accounts MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.79 - 622c0827-31cc-4751-afd5-0c1d146d015a] MSAL MSAL.Desktop with assembly version ‘4.36.1.0’. CorrelationId(622c0827-31cc-4751-afd5-0c1d146d015a) MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.80 - 622c0827-31cc-4751-afd5-0c1d146d015a] === AcquireTokenSilent Parameters === MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.80 - 622c0827-31cc-4751-afd5-0c1d146d015a] LoginHint provided: False MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.80 - 622c0827-31cc-4751-afd5-0c1d146d015a] Account provided: True MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.80 - 622c0827-31cc-4751-afd5-0c1d146d015a] ForceRefresh: False “MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.81 - 622c0827-31cc-4751-afd5-0c1d146d015a] === Request Data === Authority Provided? - True Scopes - files.read.all Extra Query Params Keys (space separated) - ApiId - AcquireTokenSilent IsConfidentialClient - False SendX5C - False LoginHint ? False IsBrokerConfigured - False HomeAccountId - False CorrelationId - 622c0827-31cc-4751-afd5-0c1d146d015a” “MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.81 - 622c0827-31cc-4751-afd5-0c1d146d015a] === Token Acquisition (SilentRequest) started: Scopes: files.read.all Authority Host: login.microsoftonline.com” MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.83 - 622c0827-31cc-4751-afd5-0c1d146d015a] [Region discovery] Azure region was not configured or could not be discovered. Not using a regional authority. MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.83 - 622c0827-31cc-4751-afd5-0c1d146d015a] Access token is not expired. Returning the found cache entry. [Current time (01/20/2022 14:18:19) - Expiration Time (01/20/2022 14:34:04 +00:00) - Extended Expiration Time (01/20/2022 14:34:04 +00:00)] MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.83 - 622c0827-31cc-4751-afd5-0c1d146d015a] Returning access token found in cache. RefreshOn exists ? False MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.84 - 622c0827-31cc-4751-afd5-0c1d146d015a] [Region discovery] Azure region was not configured or could not be discovered. Not using a regional authority. MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.90 - 622c0827-31cc-4751-afd5-0c1d146d015a] Fetched access token from host login.microsoftonline.com. “MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.91 - 622c0827-31cc-4751-afd5-0c1d146d015a] === Token Acquisition finished successfully:” MSAL: False MSAL 4.36.1.0 MSAL.Desktop 4.8 or later Windows 10 Enterprise [01-20 14:18:19.91 - 622c0827-31cc-4751-afd5-0c1d146d015a] AT expiration time: 20-1-2022 14:34:04 +00:00, scopes Files.Read.All openid profile User.Read email source Cache from login.microsoftonline.com appHashCode 32290900

Which version of MSAL.NET are you using? MSAL.NET 4.36.1

Platform .NET Framework 4.8 (VSTO Addin)

What authentication flow has the issue?

  • Desktop / Mobile *** [ X] Interactive**
    • Integrated Windows Authentication
    • Username Password
    • Device code flow (browserless)
  • Web app
    • Authorization code
    • On-Behalf-Of
  • Daemon app
    • Service to Service calls

Other?

Is this a new or existing app? a. The app is in production, and I have upgraded to a new version of MSAL. b. The app is in production, I haven’t upgraded MSAL, but started seeing this issue. c. This is a new app or experiment.

Repro

		private string Tenant { get; }  = "organizations";
		private string Instance { get; }  = "https://login.microsoftonline.com/";
		private string[] Scopes { get; }  = new string[] { "files.read.all" };

...
		public override AuthenticateResponse Authenticate()
		{
			AuthenticationResult authResult = null;

			IAccount firstAccount;
			if (ClientApp == null)
				throw new AuthenticationException("ClientApp not available");

			var accounts = ClientApp.GetAccountsAsync().Result;
			firstAccount = accounts.FirstOrDefault();

			try
			{
				try
				{
					authResult = ClientApp.AcquireTokenSilent(Scopes, firstAccount).ExecuteAsync().Result;
				}
				catch (AggregateException ae)
				{
					foreach (var e in ae.InnerExceptions)
					{
						throw e;
					}
				}
			}
			catch (MsalUiRequiredException msalException)
			{
				// A MsalUiRequiredException happened on AcquireTokenSilent. 
				// This indicates you need to call AcquireTokenInteractive to acquire a token
				_logger.WriteError(() => $"MsalUiRequiredException: {msalException.Message}");

				try
				{
					// Windows authentication
					authResult = ClientApp.AcquireTokenByIntegratedWindowsAuth(Scopes).ExecuteAsync().Result;
				}
				catch (Exception ex)
				{
					_logger.WriteError(() => $"Error Acquiring Integrated Windows Token:{System.Environment.NewLine}{ex}");
					throw new AuthenticationUIRequiredException();
				}
			}

			return getServiceStackBearerTokenByMSALIDToken(authResult);
		}

Expected behavior When ID token is expired then a new ID token should be requested by AcquireTokenSilent() call.

Actual behavior The ID token is only refreshed when Access token is expired.

Possible solution Maybe, I should also specify more scopes as suggested here: Important The Microsoft Authentication Library (MSAL) currently specifies offline_access, openid, profile, and email by default in authorization and token requests. This means that, for the default case, if you specify these permissions explicitly, Azure AD may return an error. https://docs.microsoft.com/nl-nl/graph/permissions-reference#openid-permissions

Additional context / logs / screenshots / links to code We have a VSTO Addin which connect with a REST service. To connect with this REST service the user must identify itself with a valid ID token. The access token (scope=files.read.all) is used in the VSTO addin to download files from SharePoint online, but not to call our REST service.

The ID token can have a different lifetime than the Access token. Say, for example the ID token is valid for 55 min, but the Access token is valid for 60 min. Then the user cannot login to our application in the 5 min. timespan.

I cannot not prove this bug easily with the steps to reproduce it, because I have to wait for the exact moment, but I have experienced this issue today 2022-01-20_15-18-36 .

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
digiofficerobincommented, Jan 24, 2022

Interesting, I never thought that the 2 tokens have different expirations. Looks like they are some 10 min difference between them (AT lasts more that IDT). @hpsin @maliksahil @yordan-msft - do you know why this is? Should MSAL do the refresh_token flow on the minimum(at_exp, id_exp)?

I think the workaround for you is to use .WithForceRefresh(true) which will force new tokens to be acquired silently WHEN the id token is about to expire. This is available on AcquireTokenSilent builder.

As a workaround I’ve changed my code for getting a silent token in a two-step approach:

authResult = ClientApp.AcquireTokenSilent(Scopes, firstAccount).ExecuteAsync().Result;

if (!isAccessAndIDTokenValid(authResult))
{
	authResult = ClientApp.AcquireTokenSilent(Scopes, firstAccount).WithForceRefresh(true).ExecuteAsync().Result;
}
private bool isAccessAndIDTokenValid(AuthenticationResult authResult)
{
	return isTokenValid(new JwtSecurityToken(authResult.AccessToken)) && isTokenValid(new JwtSecurityToken(authResult.IdToken));
}

private static bool isTokenValid(JwtSecurityToken token) => token.ValidTo > DateTime.UtcNow;
0reactions
bgavrilMScommented, Dec 22, 2022

Closing this as known issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What Are Refresh Tokens and How to Use Them Securely
The refresh is only valid within the lifespan of the access token, which would be short-lived. Use Refresh Tokens in Your Auth0 Apps....
Read more >
Refresh token has same expiration as accessToken and ...
I've been noticing lately that my refresh token has the same expiration time as my access and id tokens.
Read more >
Refresh tokens in the Microsoft identity platform
Refresh tokens sent to a redirect URI registered as spa expire after 24 hours. Additional refresh tokens acquired using the initial refresh ......
Read more >
What is intent of ID Token expiry time in OpenID Connect?
Any ID token expiry time less than the expiry time of the refresh token will mean you will eventually have an expired ID...
Read more >
Using the refresh token - Amazon Cognito
You can use the refresh token to retrieve new ID and access tokens. By default, the refresh token expires 30 days after your...
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