internal async Task <AuthenticationResult> HandleTokenRefreshErrorAsync(MsalServiceException e, MsalAccessTokenCacheItem cachedAccessTokenItem) { var logger = AuthenticationRequestParameters.RequestContext.Logger; bool isAadUnavailable = e.IsAadUnavailable(); logger.Warning($"Fetching a new AT 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. "); var idToken = await CacheManager.GetIdTokenCacheItemAsync(cachedAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); var tenantProfiles = await CacheManager.GetTenantProfilesAsync(cachedAccessTokenItem.HomeAccountId).ConfigureAwait(false); return(new AuthenticationResult( cachedAccessTokenItem, idToken, tenantProfiles?.Values, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent)); } logger.Warning("Either the exception does not indicate a problem with AAD or the token cache does not have an AT that is usable. "); throw e; }
private async Task <AuthenticationResult> CreateAuthenticationResultAsync(MsalAccessTokenCacheItem cachedAccessTokenItem) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(cachedAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); return(new AuthenticationResult( cachedAccessTokenItem, msalIdTokenItem, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId)); }
internal override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (TokenCache == null) { throw new MsalUiRequiredException( MsalUiRequiredException.TokenCacheNullError, "Token cache is set to null. Silent requests cannot be executed."); } MsalAccessTokenCacheItem msalAccessTokenItem = null; // Look for access token if (!ForceRefresh) { msalAccessTokenItem = await TokenCache.FindAccessTokenAsync(AuthenticationRequestParameters).ConfigureAwait(false); } if (msalAccessTokenItem != null) { var msalIdTokenItem = TokenCache.GetIdTokenCacheItem( msalAccessTokenItem.GetIdTokenItemKey(), AuthenticationRequestParameters.RequestContext); return(new AuthenticationResult(msalAccessTokenItem, msalIdTokenItem)); } var msalRefreshTokenItem = await TokenCache.FindRefreshTokenAsync(AuthenticationRequestParameters).ConfigureAwait(false); if (msalRefreshTokenItem == null) { AuthenticationRequestParameters.RequestContext.Logger.Verbose("No Refresh Token was found in the cache"); throw new MsalUiRequiredException( MsalUiRequiredException.NoTokensFoundError, "No Refresh Token found in the cache"); } AuthenticationRequestParameters.RequestContext.Logger.Verbose("Refreshing access token..."); await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); var msalTokenResponse = await SendTokenRequestAsync(GetBodyParameters(msalRefreshTokenItem.Secret), cancellationToken) .ConfigureAwait(false); if (msalTokenResponse.RefreshToken == null) { msalTokenResponse.RefreshToken = msalRefreshTokenItem.Secret; AuthenticationRequestParameters.RequestContext.Logger.Info( "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead"); } return(CacheTokenResponseAndCreateAuthenticationResult(msalTokenResponse)); }
public MsalIdTokenCacheItem GetIdToken(MsalAccessTokenCacheItem accessTokenCacheItem) { string partitionKey = CacheKeyFactory.GetIdTokenKeyFromCachedItem(accessTokenCacheItem); IdTokenCacheDictionary.TryGetValue(partitionKey, out var partition); if (partition != null && partition.TryGetValue(accessTokenCacheItem.GetIdTokenItemKey().ToString(), out var idToken)) { return(idToken); } _logger.WarningPii( $"Could not find an id token for the access token with key {accessTokenCacheItem.GetKey()}", $"Could not find an id token for the access token for realm {accessTokenCacheItem.TenantId} "); return(null); }
private async Task <AuthenticationResult> CreateAuthenticationResultAsync(MsalAccessTokenCacheItem cachedAccessTokenItem) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(cachedAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); var tenantProfiles = await CacheManager.GetTenantProfilesAsync(cachedAccessTokenItem.HomeAccountId).ConfigureAwait(false); return(new AuthenticationResult( cachedAccessTokenItem, msalIdTokenItem, tenantProfiles?.Values, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent)); }
protected override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (AuthenticationRequestParameters.Scope == null || AuthenticationRequestParameters.Scope.Count == 0) { throw new MsalClientException( MsalError.ScopesRequired, MsalErrorMessage.ScopesRequired); } await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); // 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. We should not use Refresh Token // for the user because the new incoming token may have updated claims // like mfa etc. MsalAccessTokenCacheItem msalAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (msalAccessTokenItem != null) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(msalAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); AuthenticationRequestParameters.RequestContext.Logger.Info( "OBO found a valid access token in the cache. ID token also found? " + (msalIdTokenItem != null)); AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; return(new AuthenticationResult( msalAccessTokenItem, msalIdTokenItem, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache)); } var msalTokenResponse = await SendTokenRequestAsync(GetBodyParameters(), cancellationToken).ConfigureAwait(false); return(await CacheTokenResponseAndCreateAuthenticationResultAsync(msalTokenResponse).ConfigureAwait(false)); }
public MsalIdTokenCacheItem GetIdToken(MsalAccessTokenCacheItem accessTokenCacheItem) { return(MsalIdTokenCacheItem.FromJsonString( _idTokenSharedPreference.GetString(accessTokenCacheItem.GetIdTokenItemKey().ToString(), null))); }
protected override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (AuthenticationRequestParameters.Scope == null || AuthenticationRequestParameters.Scope.Count == 0) { throw new MsalClientException( MsalError.ScopesRequired, MsalErrorMessage.ScopesRequired); } await ResolveAuthorityEndpointsAsync().ConfigureAwait(false); CacheInfoTelemetry cacheInfoTelemetry = CacheInfoTelemetry.None; MsalAccessTokenCacheItem msalAccessTokenItem = null; var logger = AuthenticationRequestParameters.RequestContext.Logger; if (!_onBehalfOfParameters.ForceRefresh) { // 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. We should not use Refresh Token // for the user because the new incoming token may have updated claims // like MFA etc. msalAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (msalAccessTokenItem != null && !msalAccessTokenItem.NeedsRefresh()) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(msalAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); AuthenticationRequestParameters.RequestContext.Logger.Info( "OBO found a valid access token in the cache. ID token also found? " + (msalIdTokenItem != null)); AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; return(new AuthenticationResult( msalAccessTokenItem, msalIdTokenItem, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent)); } cacheInfoTelemetry = (msalAccessTokenItem == null) ? CacheInfoTelemetry.NoCachedAT : CacheInfoTelemetry.RefreshIn; } else { logger.Info("Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. "); cacheInfoTelemetry = CacheInfoTelemetry.ForceRefresh; } if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo == (int)CacheInfoTelemetry.None) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = (int)cacheInfoTelemetry; } // No AT in the cache or AT needs to be refreshed try { return(await FetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false)); } catch (MsalServiceException e) { return(HandleTokenRefreshError(e, msalAccessTokenItem)); } }
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 msalAccessTokenItem = null; var logger = AuthenticationRequestParameters.RequestContext.Logger; CacheInfoTelemetry cacheInfoTelemetry; 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")) { msalAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); } if (msalAccessTokenItem != null && !msalAccessTokenItem.NeedsRefresh()) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(msalAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); var tenantProfiles = await CacheManager.GetTenantProfilesAsync(msalAccessTokenItem.HomeAccountId).ConfigureAwait(false); logger.Info( "[OBO Request] Found a valid access token in the cache. ID token also found? " + (msalIdTokenItem != null)); AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true; Metrics.IncrementTotalAccessTokensFromCache(); return(new AuthenticationResult( msalAccessTokenItem, msalIdTokenItem, tenantProfiles?.Values, AuthenticationRequestParameters.AuthenticationScheme, AuthenticationRequestParameters.RequestContext.CorrelationId, TokenSource.Cache, AuthenticationRequestParameters.RequestContext.ApiEvent)); } cacheInfoTelemetry = (msalAccessTokenItem == null) ? CacheInfoTelemetry.NoCachedAT : CacheInfoTelemetry.RefreshIn; logger.Verbose($"[OBO request] No valid access token found because {cacheInfoTelemetry} "); } else { logger.Info("[OBO Request] Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. "); cacheInfoTelemetry = CacheInfoTelemetry.ForceRefresh; } if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo == (int)CacheInfoTelemetry.None) { AuthenticationRequestParameters.RequestContext.ApiEvent.CacheInfo = (int)cacheInfoTelemetry; } // No AT in the cache or AT needs to be refreshed try { return(await RefreshRtOrFetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false)); } catch (MsalServiceException e) { return(await HandleTokenRefreshErrorAsync(e, msalAccessTokenItem).ConfigureAwait(false)); } }
internal override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { if (!CacheManager.HasCache) { throw new MsalUiRequiredException( MsalError.TokenCacheNullError, MsalErrorMessage.NullTokenCacheForSilentError); } // Look for access token if (!_silentParameters.ForceRefresh) { MsalAccessTokenCacheItem msalAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (msalAccessTokenItem != null) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(msalAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); return(new AuthenticationResult(msalAccessTokenItem, msalIdTokenItem, AuthenticationRequestParameters.RequestContext.CorrelationId)); } } // Try FOCI first MsalTokenResponse msalTokenResponse = await TryGetTokenUsingFociAsync(cancellationToken) .ConfigureAwait(false); // Normal, non-FOCI flow if (msalTokenResponse == null) { // Look for a refresh token MsalRefreshTokenCacheItem appRefreshToken = await FindRefreshTokenOrFailAsync() .ConfigureAwait(false); msalTokenResponse = await RefreshAccessTokenAsync(appRefreshToken, cancellationToken) .ConfigureAwait(false); } return(await CacheTokenResponseAndCreateAuthenticationResultAsync(msalTokenResponse).ConfigureAwait(false)); }
public MsalIdTokenCacheItem GetIdToken(MsalAccessTokenCacheItem accessTokenCacheItem) { var idTokenKey = accessTokenCacheItem.GetIdTokenItemKey(); return(MsalIdTokenCacheItem.FromJsonString(GetPayload(idTokenKey))); }
internal override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken) { // Look for access token if (!_silentParameters.ForceRefresh) { MsalAccessTokenCacheItem msalAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false); if (msalAccessTokenItem != null) { var msalIdTokenItem = await CacheManager.GetIdTokenCacheItemAsync(msalAccessTokenItem.GetIdTokenItemKey()).ConfigureAwait(false); return(new AuthenticationResult(msalAccessTokenItem, msalIdTokenItem, AuthenticationRequestParameters.RequestContext.CorrelationId)); } } return(await RefreshRTAsync(cancellationToken).ConfigureAwait(false)); }