Example #1
0
        private static void AssertThrottlingCacheEntryCount(
            SingletonThrottlingManager throttlingManager,
            int retryAfterEntryCount = 0,
            int httpStatusEntryCount = 0,
            int uiRequiredEntryCount = 0)
        {
            var(retryAfterProvider, httpStatusProvider, uiRequiredProvider) =
                throttlingManager.GetTypedThrottlingProviders();

            Assert.AreEqual(retryAfterEntryCount, retryAfterProvider.ThrottlingCache.CacheForTest.Count);
            Assert.AreEqual(httpStatusEntryCount, httpStatusProvider.ThrottlingCache.CacheForTest.Count);
            Assert.AreEqual(uiRequiredEntryCount, uiRequiredProvider.ThrottlingCache.CacheForTest.Count);
        }
Example #2
0
        public async Task ATS_NonExpired_NeedsRefresh_AADUnavailableResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app with a token cache with one AT");
                PublicClientApplication app = SetupPca(harness);

                Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed");
                UpdateATWithRefreshOn(app.UserTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1));
                TokenCacheAccessRecorder cacheAccess = app.UserTokenCache.RecordAccess();

                Trace.WriteLine("3. Configure AAD to respond with a 500 error");
                harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503);
                harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503);


                // Act
                var account = new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null);
                AuthenticationResult result = await app
                                              .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    account)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                // Assert
                Assert.IsNotNull(result, "ATS still succeeds even though AAD is unavaible");
                Assert.AreEqual(0, harness.HttpManager.QueueSize);
                cacheAccess.AssertAccessCounts(1, 0); // the refresh failed, no new data is written to the cache

                // reset throttling, otherwise MSAL would block similar requests for 2 minutes
                // and we would still get a cached response
                SingletonThrottlingManager.GetInstance().ResetCache();

                // Now let AAD respond with tokens
                harness.HttpManager.AddTokenResponse(TokenResponseType.Valid);

                result = await app
                         .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    account)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

                Assert.IsNotNull(result);
                cacheAccess.AssertAccessCounts(2, 1); // new tokens written to cache
            }
        }
        internal ServiceBundle(
            ApplicationConfiguration config,
            bool shouldClearCaches = false)
        {
            Config = config;

            ApplicationLogger = new MsalLogger(
                Guid.Empty,
                config.ClientName,
                config.ClientVersion,
                config.LogLevel,
                config.EnablePiiLogging,
                config.IsDefaultPlatformLoggingEnabled,
                config.LoggingCallback);

            PlatformProxy = config.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(ApplicationLogger);
            HttpManager   = config.HttpManager ?? new HttpManager(
                config.HttpClientFactory ??
                PlatformProxy.CreateDefaultHttpClientFactory());

            HttpTelemetryManager = new HttpTelemetryManager();
            if (config.TelemetryConfig != null)
            {
                // This can return null if the device isn't sampled in.  There's no need for processing MATS events if we're not going to send them.
                Mats = TelemetryClient.CreateMats(config, PlatformProxy, config.TelemetryConfig);
                MatsTelemetryManager = Mats?.TelemetryManager ??
                                       new TelemetryManager(config, PlatformProxy, config.TelemetryCallback);
            }
            else
            {
                MatsTelemetryManager = new TelemetryManager(config, PlatformProxy, config.TelemetryCallback);
            }

            InstanceDiscoveryManager = new InstanceDiscoveryManager(
                HttpManager,
                shouldClearCaches,
                config.CustomInstanceDiscoveryMetadata,
                config.CustomInstanceDiscoveryMetadataUri);

            WsTrustWebRequestManager = new WsTrustWebRequestManager(HttpManager);
            ThrottlingManager        = SingletonThrottlingManager.GetInstance();
            DeviceAuthManager        = config.DeviceAuthManagerForTest ?? PlatformProxy.CreateDeviceAuthManager();

            if (shouldClearCaches)
            {
                AuthorityManager.ClearValidationCache();
            }
        }
Example #4
0
        internal ServiceBundle(
            ApplicationConfiguration config,
            bool shouldClearCaches = false)
        {
            Config = config;

            ApplicationLogger = new MsalLogger(
                Guid.Empty,
                config.ClientName,
                config.ClientVersion,
                config.LogLevel,
                config.EnablePiiLogging,
                config.IsDefaultPlatformLoggingEnabled,
                config.LoggingCallback);

            PlatformProxy = config.PlatformProxy ?? PlatformProxyFactory.CreatePlatformProxy(ApplicationLogger);
            HttpManager   = config.HttpManager ?? new HttpManager(
                config.HttpClientFactory ??
                PlatformProxy.CreateDefaultHttpClientFactory());

            HttpTelemetryManager = new HttpTelemetryManager();

            InstanceDiscoveryManager = new InstanceDiscoveryManager(
                HttpManager,
                shouldClearCaches,
                config.CustomInstanceDiscoveryMetadata,
                config.CustomInstanceDiscoveryMetadataUri);

            WsTrustWebRequestManager = new WsTrustWebRequestManager(HttpManager);
            ThrottlingManager        = SingletonThrottlingManager.GetInstance();
            DeviceAuthManager        = config.DeviceAuthManagerForTest ?? PlatformProxy.CreateDeviceAuthManager();

            if (shouldClearCaches) // for test
            {
                AuthorityManager.ClearValidationCache();
                PoPProviderFactory.Reset();
            }
        }
Example #5
0
        public async Task ATS_NonExpired_NeedsRefresh_AADUnavailableResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app with a token cache with one AT");
                PublicClientApplication app = SetupPca(harness);

                Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed");
                UpdateATWithRefreshOn(app.UserTokenCacheInternal.Accessor);
                TokenCacheAccessRecorder cacheAccess = app.UserTokenCache.RecordAccess();

                Trace.WriteLine("3. Configure AAD to respond with a 500 error");
                harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503);
                harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503);

                // Act
                var account = new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null);
                AuthenticationResult result = await app
                                              .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    account)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                // The following can be indeterministic due to background threading nature
                // So it is verified on check and wait basis
                Assert.IsTrue(YieldTillSatisfied(() => harness.HttpManager.QueueSize == 0), "Background refresh 1 did not execute.");

                // Assert
                Assert.AreEqual(0, harness.HttpManager.QueueSize);
                Assert.AreEqual(CacheRefreshReason.ProactivelyRefreshed, result.AuthenticationResultMetadata.CacheRefreshReason);

                cacheAccess.WaitTo_AssertAcessCounts(1, 0); // the refresh failed, no new data is written to the cache

                // reset throttling, otherwise MSAL would block similar requests for 2 minutes
                // and we would still get a cached response
                SingletonThrottlingManager.GetInstance().ResetCache();

                // Now let AAD respond with tokens
                harness.HttpManager.AddTokenResponse(TokenResponseType.Valid_UserFlows);

                result = await app
                         .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    account)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

                Assert.AreEqual(CacheRefreshReason.ProactivelyRefreshed, result.AuthenticationResultMetadata.CacheRefreshReason);

                Assert.IsTrue(YieldTillSatisfied(
                                  () => harness.HttpManager.QueueSize == 0),
                              "Background refresh 2 did not execute.");
                Assert.IsTrue(
                    YieldTillSatisfied(() => cacheAccess.AfterAccessTotalCount == 3),
                    "The background refresh executed, but the cache was not updated");

                cacheAccess.WaitTo_AssertAcessCounts(2, 1); // new tokens written to cache
            }
        }