private static void AssertCurrentTelemetry( HttpRequestMessage requestMessage, ApiIds apiId, CacheRefreshReason cacheInfo, bool isCacheSerialized = false, bool isLegacyCacheEnabled = true) { string[] telemetryCategories = requestMessage.Headers.GetValues( TelemetryConstants.XClientCurrentTelemetry).Single().Split('|'); Assert.AreEqual(3, telemetryCategories.Length); Assert.AreEqual(1, telemetryCategories[0].Split(',').Length); // version Assert.AreEqual(5, telemetryCategories[1].Split(',').Length); // api_id, cache_info, region_used, region_source, region_outcome Assert.AreEqual(2, telemetryCategories[2].Split(',').Length); // platform_fields Assert.AreEqual(TelemetryConstants.HttpTelemetrySchemaVersion, telemetryCategories[0]); // version Assert.AreEqual( apiId.ToString("D"), telemetryCategories[1].Split(',')[0]); // current_api_id Assert.AreEqual(cacheInfo.ToString("D"), telemetryCategories[1].Split(',')[1]); // cache_info Assert.AreEqual(isCacheSerialized ? "1" : "0", telemetryCategories[2].Split(',')[0]); // is_cache_serialized Assert.AreEqual(isLegacyCacheEnabled ? "1" : "0", telemetryCategories[2].Split(',')[1]); // is_legacy_cache_enabled }
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)); } }
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); } 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)); } }