public async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { var logger = AuthenticationRequestParameters.RequestContext.Logger; MsalAccessTokenCacheItem cachedAccessTokenItem = null; CacheRefreshReason cacheInfoTelemetry = CacheRefreshReason.NotApplicable; ThrowIfNoScopesOnB2C(); ThrowIfCurrentBrokerAccount(); AuthenticationResult authResult = null; if (!_silentParameters.ForceRefresh && string.IsNullOrEmpty(AuthenticationRequestParameters.Claims)) { cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (cachedAccessTokenItem != null) { logger.Info("Returning access token found in cache. RefreshOn exists ? " + cachedAccessTokenItem.RefreshOn.HasValue); AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; Metrics.IncrementTotalAccessTokensFromCache(); authResult = await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false); } else { if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo != CacheRefreshReason.Expired) { cacheInfoTelemetry = CacheRefreshReason.NoCachedAccessToken; } } } else { cacheInfoTelemetry = CacheRefreshReason.ForceRefreshOrClaims; logger.Info("Skipped looking for an Access Token because ForceRefresh or Claims were set. "); } if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo == CacheRefreshReason.NotApplicable) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = cacheInfoTelemetry; } // No AT or AT neesd to be refreshed try { if (cachedAccessTokenItem == null) { authResult = await RefreshRtOrFailAsync(cancellationToken).ConfigureAwait(false); } else { var shouldRefresh = SilentRequestHelper.NeedsRefresh(cachedAccessTokenItem); // may fire a request to get a new token in the background if (shouldRefresh) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = CacheRefreshReason.ProactivelyRefreshed; SilentRequestHelper.ProcessFetchInBackground( cachedAccessTokenItem, () => RefreshRtOrFailAsync(cancellationToken), logger); } } return(authResult); } catch (MsalServiceException e) { bool isAadUnavailable = e.IsAadUnavailable(); logger.Warning($"Refreshing the RT failed. Is AAD down? {isAadUnavailable}. Is there an AT in the cache that is usable? {cachedAccessTokenItem != null} "); if (cachedAccessTokenItem != null && isAadUnavailable) { logger.Info("Returning existing access token. It is not expired, but should be refreshed. "); return(await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false)); } logger.Warning("Failed to refresh the RT and cannot use existing AT (expired or missing). "); throw; } }
protected override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (AuthenticationRequestParameters.Scope == null || AuthenticationRequestParameters.Scope.Count == 0) { throw new MsalClientException( MsalError.ScopesRequired, MsalErrorMessage.ScopesRequired); } MsalAccessTokenCacheItem cachedAccessTokenItem = null; var logger = AuthenticationRequestParameters.RequestContext.Logger; CacheRefreshReason cacheInfoTelemetry = CacheRefreshReason.NotApplicable; AuthenticationResult authResult = null; if (AuthenticationRequestParameters.Authority is AadAuthority aadAuthority && aadAuthority.IsCommonOrOrganizationsTenant()) { logger.Error(MsalErrorMessage.ClientCredentialWrongAuthority); } if (!_clientParameters.ForceRefresh && string.IsNullOrEmpty(AuthenticationRequestParameters.Claims)) { cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (cachedAccessTokenItem != null) { AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; Metrics.IncrementTotalAccessTokensFromCache(); authResult = new AuthenticationResult( cachedAccessTokenItem, null, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent, null); } else { if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo != CacheRefreshReason.Expired) { cacheInfoTelemetry = CacheRefreshReason.NoCachedAccessToken; } } } else { cacheInfoTelemetry = CacheRefreshReason.ForceRefreshOrClaims; logger.Info("Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. "); } if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo == CacheRefreshReason.NotApplicable) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = cacheInfoTelemetry; } // No AT in the cache or AT needs to be refreshed try { if (cachedAccessTokenItem == null) { authResult = await FetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false); } else { var shouldRefresh = SilentRequestHelper.NeedsRefresh(cachedAccessTokenItem); // may fire a request to get a new token in the background if (shouldRefresh) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = CacheRefreshReason.ProactivelyRefreshed; SilentRequestHelper.ProcessFetchInBackground( cachedAccessTokenItem, () => FetchNewAccessTokenAsync(cancellationToken), logger); } } return(authResult); } catch (MsalServiceException e) { return(await HandleTokenRefreshErrorAsync(e, cachedAccessTokenItem).ConfigureAwait(false)); } }
protected override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (AuthenticationRequestParameters.Scope == null || AuthenticationRequestParameters.Scope.Count == 0) { throw new MsalClientException( MsalError.ScopesRequired, MsalErrorMessage.ScopesRequired); } await ResolveAuthorityAsync().ConfigureAwait(false); MsalAccessTokenCacheItem cachedAccessToken = null; var logger = AuthenticationRequestParameters.RequestContext.Logger; AuthenticationResult authResult = null; CacheRefreshReason cacheInfoTelemetry = CacheRefreshReason.NotApplicable; if (!_onBehalfOfParameters.ForceRefresh && string.IsNullOrEmpty(AuthenticationRequestParameters.Claims)) { // look for access token in the cache first. // no access token is found, then it means token does not exist // or new assertion has been passed. // Look for a refresh token, if refresh token is found perform refresh token flow. // If a refresh token is not found, then it means refresh token does not exist or new assertion has been passed. // Fetch new access token for OBO using (logger.LogBlockDuration("[OBO Request] Looking in the cache for an access token")) { cachedAccessToken = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); } if (cachedAccessToken != null) { var cachedIdToken = await CacheManager.GetIdTokenCacheItemAsync(cachedAccessToken).ConfigureAwait(false); var account = await CacheManager.GetAccountAssociatedWithAccessTokenAsync(cachedAccessToken).ConfigureAwait(false); logger.Info( "[OBO Request] Found a valid access token in the cache. ID token also found? " + (cachedIdToken != null)); AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; Metrics.IncrementTotalAccessTokensFromCache(); authResult = new AuthenticationResult( cachedAccessToken, cachedIdToken, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent, account); } else { if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo != CacheRefreshReason.Expired) { cacheInfoTelemetry = CacheRefreshReason.NoCachedAccessToken; } } } else { logger.Info("[OBO Request] Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. "); cacheInfoTelemetry = CacheRefreshReason.ForceRefreshOrClaims; } if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo == CacheRefreshReason.NotApplicable) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = cacheInfoTelemetry; } // No AT in the cache or AT needs to be refreshed try { if (cachedAccessToken == null) { authResult = await RefreshRtOrFetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false); } else { var shouldRefresh = SilentRequestHelper.NeedsRefresh(cachedAccessToken); // may fire a request to get a new token in the background if (shouldRefresh) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = CacheRefreshReason.ProactivelyRefreshed; SilentRequestHelper.ProcessFetchInBackground( cachedAccessToken, () => RefreshRtOrFetchNewAccessTokenAsync(cancellationToken), logger); } } return(authResult); } catch (MsalServiceException e) { return(await HandleTokenRefreshErrorAsync(e, cachedAccessToken).ConfigureAwait(false)); } }