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;
            CacheInfoTelemetry cacheInfoTelemetry = CacheInfoTelemetry.None;

            if (!_clientParameters.ForceRefresh &&
                string.IsNullOrEmpty(AuthenticationRequestParameters.Claims))
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true;

                    Metrics.IncrementTotalAccessTokensFromCache();
                    return(new AuthenticationResult(
                               cachedAccessTokenItem,
                               null,
                               null,
                               AuthenticationRequestParameters.AuthenticationScheme,
                               AuthenticationRequestParameters.RequestContext.CorrelationId,
                               TokenSource.Cache,
                               AuthenticationRequestParameters.RequestContext.ApiEvent));
                }

                cacheInfoTelemetry = (cachedAccessTokenItem == null) ? CacheInfoTelemetry.NoCachedAT : CacheInfoTelemetry.RefreshIn;
            }
            else
            {
                logger.Info("Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. ");

                if (_clientParameters.ForceRefresh)
                {
                    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(await HandleTokenRefreshErrorAsync(e, cachedAccessTokenItem).ConfigureAwait(false));
            }
        }
        internal override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken)
        {
            MsalAccessTokenCacheItem cachedAccessTokenItem = null;
            var logger = AuthenticationRequestParameters.RequestContext.Logger;

            if (!_clientParameters.ForceRefresh)
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    return(new AuthenticationResult(cachedAccessTokenItem, null, AuthenticationRequestParameters.RequestContext.CorrelationId));
                }
            }

            // No AT in the cache or AT needs to be refreshed
            try
            {
                return(await FetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false));
            }
            catch (MsalServiceException e)
            {
                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.");
                    return(new AuthenticationResult(cachedAccessTokenItem, null, AuthenticationRequestParameters.RequestContext.CorrelationId));
                }

                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;
            }
        }
Пример #3
0
        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;

            if (!_clientParameters.ForceRefresh &&
                string.IsNullOrEmpty(AuthenticationRequestParameters.Claims))
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true;

                    return(new AuthenticationResult(
                               cachedAccessTokenItem,
                               null,
                               AuthenticationRequestParameters.AuthenticationScheme,
                               AuthenticationRequestParameters.RequestContext.CorrelationId,
                               TokenSource.Cache));
                }
            }
            else
            {
                logger.Info("Skipped looking for an Access Token in the cache because ForceRefresh or Claims were set. ");
            }

            // No AT in the cache or AT needs to be refreshed
            try
            {
                return(await FetchNewAccessTokenAsync(cancellationToken).ConfigureAwait(false));
            }
            catch (MsalServiceException e)
            {
                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. ");
                    return(new AuthenticationResult(
                               cachedAccessTokenItem,
                               null,
                               AuthenticationRequestParameters.AuthenticationScheme,
                               AuthenticationRequestParameters.RequestContext.CorrelationId,
                               TokenSource.Cache));
                }

                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;
            }
        }
        public async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken)
        {
            var logger = AuthenticationRequestParameters.RequestContext.Logger;
            MsalAccessTokenCacheItem cachedAccessTokenItem = null;

            ThrowIfNoScopesOnB2C();
            ThrowIfCurrentBrokerAccount();

            if (!_silentParameters.ForceRefresh && string.IsNullOrEmpty(AuthenticationRequestParameters.Claims))
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    logger.Info("Returning access token found in cache. RefreshOn exists ? "
                                + cachedAccessTokenItem.RefreshOn.HasValue);
                    AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true;
                    return(await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false));
                }
            }
            else
            {
                logger.Info("Skipped looking for an Access Token because ForceRefresh or Claims were set. ");
            }

            // No AT or AT.RefreshOn > Now --> refresh the RT
            try
            {
                return(await RefreshRtOrFailAsync(cancellationToken).ConfigureAwait(false));
            }
            catch (MsalServiceException e)
            {
                //Remove the account from cache in case of bad_token sub error
                if (MsalError.BadToken.Equals(e.SubError, StringComparison.OrdinalIgnoreCase))
                {
                    await CacheManager.TokenCacheInternal.RemoveAccountAsync(AuthenticationRequestParameters.Account, AuthenticationRequestParameters.RequestContext).ConfigureAwait(false);

                    logger.Warning("Failed to refresh access token because the refresh token is invalid, removing account from cache. ");
                    throw;
                }

                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)
        {
            var logger = AuthenticationRequestParameters.RequestContext.Logger;
            MsalAccessTokenCacheItem cachedAccessTokenItem = null;

            if (ServiceBundle.PlatformProxy.CanBrokerSupportSilentAuth() && AuthenticationRequestParameters.IsBrokerConfigured)
            {
                var msalTokenResponse = await ExecuteBrokerAsync(cancellationToken).ConfigureAwait(false);

                return(await CacheTokenResponseAndCreateAuthenticationResultAsync(msalTokenResponse).ConfigureAwait(false));
            }

            if (!_silentParameters.ForceRefresh && !AuthenticationRequestParameters.HasClaims)
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    logger.Info("Returning access token found in cache. RefreshOn exists ? "
                                + cachedAccessTokenItem.RefreshOn.HasValue);
                    return(await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false));
                }
            }
            else
            {
                logger.Info("Skipped looking for an Access Token because ForceRefresh or Claims were set");
            }

            // No AT or AT.RefreshOn > Now --> refresh the RT
            try
            {
                return(await RefreshRtOrFailAsync(cancellationToken).ConfigureAwait(false));
            }
            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;
            }
        }
Пример #6
0
        internal override async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken)
        {
            var logger = AuthenticationRequestParameters.RequestContext.Logger;
            MsalAccessTokenCacheItem cachedAccessTokenItem = null;

            // Look for access token
            if (!_silentParameters.ForceRefresh)
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    logger.Info("Returning access token found in cache. RefreshOn exists ? "
                                + cachedAccessTokenItem.RefreshOn.HasValue);
                    return(await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false));
                }
            }

            // No AT or AT.RefreshOn > Now --> refresh the RT
            try
            {
                return(await RefreshRtOrFailAsync(cancellationToken).ConfigureAwait(false));
            }
            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;
            }
        }
Пример #7
0
        public async Task <AuthenticationResult> ExecuteAsync(CancellationToken cancellationToken)
        {
            var logger = AuthenticationRequestParameters.RequestContext.Logger;
            MsalAccessTokenCacheItem cachedAccessTokenItem = null;
            CacheRefresh             cacheRefresh          = CacheRefresh.None;

            ThrowIfNoScopesOnB2C();
            ThrowIfCurrentBrokerAccount();

            if (!_silentParameters.ForceRefresh && string.IsNullOrEmpty(AuthenticationRequestParameters.Claims))
            {
                cachedAccessTokenItem = await CacheManager.FindAccessTokenAsync().ConfigureAwait(false);

                if (cachedAccessTokenItem != null && !cachedAccessTokenItem.NeedsRefresh())
                {
                    logger.Info("Returning access token found in cache. RefreshOn exists ? "
                                + cachedAccessTokenItem.RefreshOn.HasValue);
                    AuthenticationRequestParameters.RequestContext.ApiEvent.IsAccessTokenCacheHit = true;
                    return(await CreateAuthenticationResultAsync(cachedAccessTokenItem).ConfigureAwait(false));
                }
                else if (cachedAccessTokenItem == null)
                {
                    cacheRefresh = CacheRefresh.NoCachedAT;
                }
                else
                {
                    cacheRefresh = CacheRefresh.RefreshIn;
                }
            }
            else
            {
                cacheRefresh = CacheRefresh.ForceRefresh;
                logger.Info("Skipped looking for an Access Token because ForceRefresh or Claims were set. ");
            }

            if (AuthenticationRequestParameters.RequestContext.ApiEvent.CacheRefresh == null)
            {
                AuthenticationRequestParameters.RequestContext.ApiEvent.CacheRefresh = (int)cacheRefresh;
            }

            // No AT or AT.RefreshOn > Now --> refresh the RT
            try
            {
                return(await RefreshRtOrFailAsync(cancellationToken).ConfigureAwait(false));
            }
            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 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));
            }
        }
Пример #9
0
        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));
            }
        }