Пример #1
0
        public async Task ClientCreds_Expired_NeedsRefresh_AADInvalidResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app with a token cache with one AT = expired and needs refersh");
                ConfidentialClientApplication app = SetupCca(harness);
                var atItem = TokenCacheHelper.CreateAccessTokenItem();
                UpdateATWithRefreshOn(atItem, DateTime.UtcNow - TimeSpan.FromMinutes(1), true);
                TokenCacheHelper.PopulateDefaultAppTokenCache(app, atItem);

                TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess();

                Trace.WriteLine("2. Configure AAD to be unavaiable");
                harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503);
                harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503);

                // Act
                MsalServiceException ex = await AssertException.TaskThrowsAsync <MsalServiceException>(() => app
                                                                                                       .AcquireTokenForClient(TestConstants.s_scope)
                                                                                                       .ExecuteAsync())
                                          .ConfigureAwait(false);

                Assert.IsFalse(ex is MsalUiRequiredException, "5xx exceptions do not translate to MsalUIRequired");
                Assert.AreEqual(503, ex.StatusCode);
                cacheAccess.AssertAccessCounts(1, 0);
            }
        }
Пример #2
0
        public async Task ClientCreds_NonExpired_NeedsRefresh_AADInvalidResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app");
                ConfidentialClientApplication app = SetupCca(harness);

                Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed");

                MsalAccessTokenCacheItem atItem = TokenCacheHelper.CreateAccessTokenItem();
                UpdateATWithRefreshOn(atItem, DateTime.UtcNow - TimeSpan.FromMinutes(1));
                TokenCacheHelper.PopulateDefaultAppTokenCache(app, atItem);

                TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess();

                Trace.WriteLine("3. Configure AAD to respond with the typical Invalid Grant error");
                harness.HttpManager.AddAllMocks(TokenResponseType.InvalidGrant);

                // Act
                await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() =>
                                                                                app.AcquireTokenForClient(TestConstants.s_scope)
                                                                                .ExecuteAsync())
                .ConfigureAwait(false);

                cacheAccess.AssertAccessCounts(1, 0);
            }
        }
Пример #3
0
        public async Task ClientCreds_NonExpired_NeedsRefresh_ValidResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app");
                ConfidentialClientApplication app = SetupCca(harness);

                Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed");
                MsalAccessTokenCacheItem atItem = TokenCacheHelper.CreateAccessTokenItem();
                UpdateATWithRefreshOn(atItem, DateTime.UtcNow - TimeSpan.FromMinutes(1));
                TokenCacheHelper.PopulateDefaultAppTokenCache(app, atItem);

                TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess();

                Trace.WriteLine("3. Configure AAD to respond with valid token to the refresh RT flow");
                harness.HttpManager.AddAllMocks(TokenResponseType.Valid);

                // Act
                Trace.WriteLine("4. ATS - should perform an RT refresh");
                AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                // Assert
                Assert.IsNotNull(result);
                Assert.AreEqual(0, harness.HttpManager.QueueSize,
                                "MSAL should have refreshed the token because the original AT was marked for refresh");
                cacheAccess.AssertAccessCounts(1, 1);
            }
        }
Пример #4
0
        public async Task ClientCreds_NonExpired_NeedsRefresh_AADUnavailableResponse_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app ");
                ConfidentialClientApplication app = SetupCca(harness);

                Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed");

                MsalAccessTokenCacheItem atItem = TokenCacheHelper.CreateAccessTokenItem();
                UpdateATWithRefreshOn(atItem, DateTime.UtcNow - TimeSpan.FromMinutes(1));
                TokenCacheHelper.PopulateDefaultAppTokenCache(app, atItem);

                TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess();

                //UpdateATWithRefreshOn(app.AppTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1));


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

                // Act
                AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                // Assert
                Assert.IsNotNull(result, "ClientCreds should 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

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

                result = await app.AcquireTokenForClient(TestConstants.s_scope)
                         .ExecuteAsync()
                         .ConfigureAwait(false);

                Assert.IsNotNull(result);
                cacheAccess.AssertAccessCounts(2, 1); // new tokens written to cache
            }
        }
Пример #5
0
        public async Task AcquireTokenForClient_BypassesCacheForAccessTokens_IfClaimsUsed_Async()
        {
            // Arrange
            using (MockHttpAndServiceBundle harness = base.CreateTestHarness())
            {
                Trace.WriteLine("1. Setup an app with a token cache with one AT");
                ConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                                                    .WithAuthority(AzureCloudInstance.AzurePublic, TestConstants.Utid)
                                                    .WithClientSecret(TestConstants.ClientSecret)
                                                    .WithHttpManager(harness.HttpManager)
                                                    .BuildConcrete();

                TokenCacheHelper.PopulateDefaultAppTokenCache(app);

                Trace.WriteLine("2. AcquireTokenForClient returns from the cache ");
                AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope)
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                Assert.IsNotNull(result, "A result is obtained from the cache, i.e. without HTTP calls");

                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                var refreshHandler = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        TestConstants.UniqueId,
                        TestConstants.DisplayableId,
                        TestConstants.s_scope.ToArray())
                };
                harness.HttpManager.AddMockHandler(refreshHandler);

                // Act
                Trace.WriteLine("3. AcquireTokenForClient + Claims does not return AT from cache");
                await app.AcquireTokenForClient(TestConstants.s_scope)
                .WithClaims(TestConstants.Claims)
                .ExecuteAsync()
                .ConfigureAwait(false);

                Assert.IsNotNull(result, "An access token is no longer obtained from the cache. The RT is used to get one from the STS.");
            }
        }