private async Task RunPromptTestForUserAsync(LabResponse labResponse, Prompt prompt, bool useLoginHint)
        {
            var pca = PublicClientApplicationBuilder
                      .Create(labResponse.App.AppId)
                      .WithRedirectUri(SeleniumWebUI.FindFreeLocalhostRedirectUri())
                      .Build();

            AcquireTokenInteractiveParameterBuilder builder = pca
                                                              .AcquireTokenInteractive(s_scopes)
                                                              .WithPrompt(prompt)
                                                              .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, prompt, useLoginHint));

            if (useLoginHint)
            {
                builder = builder.WithLoginHint(labResponse.User.Upn);
            }

            AuthenticationResult result = await builder
                                          .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                                          .ConfigureAwait(false);

            await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);
        }
Ejemplo n.º 2
0
        public async Task DefaultOsBrowser_IsCancellable_AfterAWhile_Async()
        {
            // Arrange
            var redirectUri = SeleniumWebUI.FindFreeLocalhostRedirectUri();
            var cts         = new CancellationTokenSource();
            IPublicClientApplication pca = InitWithCustomPlatformProxy(redirectUri);

            // Act - start with cancellation not requested
            var tokenTask = pca // do not wait for this to finish
                            .AcquireTokenInteractive(TestConstants.s_graphScopes)
                            .WithUseEmbeddedWebView(false)
                            .ExecuteAsync(cts.Token)
                            .ConfigureAwait(false);

            // Wait a bit to allow the webUI to start listening
            await Task.Delay(300).ConfigureAwait(false);

            // Cancel token acquisition while waiting for the browser to respond
            cts.Cancel();

            await ValidateOperationCancelledAsync(redirectUri, cts, tokenTask).ConfigureAwait(false);

            ValidatePortIsFree(new Uri(redirectUri).Port);
        }
Ejemplo n.º 3
0
        private async Task <AuthenticationResult> RunTestForUserAsync(LabResponse labResponse, bool directToAdfs = false)
        {
            HttpSnifferClientFactory factory = null;
            IPublicClientApplication pca;

            if (directToAdfs)
            {
                pca = PublicClientApplicationBuilder
                      .Create(Adfs2019LabConstants.PublicClientId)
                      .WithRedirectUri(Adfs2019LabConstants.ClientRedirectUri)
                      .WithAdfsAuthority(Adfs2019LabConstants.Authority)
                      .WithTestLogging()
                      .Build();
            }
            else
            {
                pca = PublicClientApplicationBuilder
                      .Create(labResponse.App.AppId)
                      .WithRedirectUri(SeleniumWebUI.FindFreeLocalhostRedirectUri())
                      .WithAuthority(labResponse.Lab.Authority + "common")
                      .WithTestLogging(out factory)
                      .Build();
            }

            var userCacheAccess = pca.UserTokenCache.RecordAccess();

            Trace.WriteLine("Part 1 - Acquire a token interactively, no login hint");
            AuthenticationResult result = await pca
                                          .AcquireTokenInteractive(s_scopes)
                                          .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.SelectAccount, false, directToAdfs))
                                          .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                                          .ConfigureAwait(false);

            Assert.IsTrue(result.AuthenticationResultMetadata.DurationTotalInMs > 0);
            Assert.IsTrue(result.AuthenticationResultMetadata.DurationInHttpInMs > 0);

            userCacheAccess.AssertAccessCounts(0, 1);
            IAccount account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 1); // the assert calls GetAccounts
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            Trace.WriteLine("Part 2 - Clear the cache");
            await pca.RemoveAsync(account).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 2);
            Assert.IsFalse((await pca.GetAccountsAsync().ConfigureAwait(false)).Any());
            userCacheAccess.AssertAccessCounts(2, 2);
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            if (factory?.RequestsAndResponses != null)
            {
                factory.RequestsAndResponses.Clear();
            }

            Trace.WriteLine("Part 3 - Acquire a token interactively again, with login hint");
            result = await pca
                     .AcquireTokenInteractive(s_scopes)
                     .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.ForceLogin, true, directToAdfs))
                     .WithPrompt(Prompt.ForceLogin)
                     .WithLoginHint(labResponse.User.Upn)
                     .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                     .ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(2, 3);
            AssertCcsRoutingInformationIsSent(factory, labResponse);

            account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(3, 3);
            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);

            if (factory?.RequestsAndResponses != null)
            {
                factory.RequestsAndResponses.Clear();
            }

            Trace.WriteLine("Part 4 - Acquire a token silently");
            result = await pca
                     .AcquireTokenSilent(s_scopes, account)
                     .ExecuteAsync(CancellationToken.None)
                     .ConfigureAwait(false);

            Trace.WriteLine("Part 5 - Acquire a token silently with force refresh");
            result = await pca
                     .AcquireTokenSilent(s_scopes, account)
                     .WithForceRefresh(true)
                     .ExecuteAsync(CancellationToken.None)
                     .ConfigureAwait(false);

            await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            Assert.IsFalse(userCacheAccess.LastAfterAccessNotificationArgs.IsApplicationCache);
            AssertCcsRoutingInformationIsSent(factory, labResponse);

            return(result);
        }
        private async Task RunTestForUserAsync(LabResponse labResponse, string authority, bool usePkce = false)
        {
            var cert = await s_secretProvider.GetCertificateWithPrivateMaterialAsync(
                CertificateName, KeyVaultInstance.MsalTeam).ConfigureAwait(false);

            IConfidentialClientApplication cca;
            string redirectUri = SeleniumWebUI.FindFreeLocalhostRedirectUri();

            HttpSnifferClientFactory factory;

            cca = ConfidentialClientApplicationBuilder
                  .Create(ConfidentialClientID)
                  .WithAuthority(authority)
                  .WithCertificate(cert)
                  .WithRedirectUri(redirectUri)
                  .WithTestLogging(out factory)
                  .Build();

            var cacheAccess = (cca as ConfidentialClientApplication).UserTokenCache.RecordAccess();

            Trace.WriteLine("Part 1 - Call GetAuthorizationRequestUrl to figure out where to go ");
            var authUriBuilder = cca
                                 .GetAuthorizationRequestUrl(s_scopes);

            string codeVerifier = "";

            if (usePkce)
            {
                authUriBuilder.WithPkce(out codeVerifier);
            }

            Uri authUri = await authUriBuilder.ExecuteAsync()
                          .ConfigureAwait(false);

            cacheAccess.AssertAccessCounts(0, 0);

            Trace.WriteLine("Part 2 - Use a browser to login and to capture the authorization code ");
            var seleniumUi = new SeleniumWebUI((driver) =>
            {
                Trace.WriteLine("Starting Selenium automation");
                driver.PerformLogin(labResponse.User, Prompt.SelectAccount, false, false);
            }, TestContext);

            CancellationTokenSource cts = new CancellationTokenSource(s_timeout);
            Uri authCodeUri             = await seleniumUi.AcquireAuthorizationCodeAsync(
                authUri,
                new Uri(redirectUri),
                cts.Token)
                                          .ConfigureAwait(false);

            var authorizationResult = AuthorizationResult.FromUri(authCodeUri.AbsoluteUri);

            Assert.AreEqual(AuthorizationStatus.Success, authorizationResult.Status);

            factory.RequestsAndResponses.Clear();

            Trace.WriteLine("Part 3 - Get a token using the auth code, just like a website");
            var result = await cca.AcquireTokenByAuthorizationCode(s_scopes, authorizationResult.Code)
                         .WithPkceCodeVerifier(codeVerifier)
                         .WithExtraHttpHeaders(TestConstants.ExtraHttpHeader)
                         .ExecuteAsync()
                         .ConfigureAwait(false);

            cacheAccess.AssertAccessCounts(0, 1);
            AssertCacheKey(cacheAccess, result.Account.HomeAccountId.Identifier);

            AssertExtraHTTPHeadersAreSent(factory);

            Trace.WriteLine("Part 4 - Remove Account");

            await cca.RemoveAsync(result.Account).ConfigureAwait(false);

            cacheAccess.AssertAccessCounts(0, 2);

            AssertCacheKey(cacheAccess, result.Account.HomeAccountId.Identifier);
        }
        private async Task <AuthenticationResult> RunTestForUserAsync(LabResponse labResponse, bool directToAdfs = false)
        {
            IPublicClientApplication pca;

            if (directToAdfs)
            {
                pca = PublicClientApplicationBuilder
                      .Create(Adfs2019LabConstants.PublicClientId)
                      .WithRedirectUri(Adfs2019LabConstants.ClientRedirectUri)
                      .WithAdfsAuthority(Adfs2019LabConstants.Authority)
                      .Build();
            }
            else
            {
                pca = PublicClientApplicationBuilder
                      .Create(labResponse.App.AppId)
                      .WithRedirectUri(SeleniumWebUI.FindFreeLocalhostRedirectUri())
                      .Build();
            }

            var userCacheAccess = pca.UserTokenCache.RecordAccess();

            Trace.WriteLine("Part 1 - Acquire a token interactively, no login hint");
            AuthenticationResult result = await pca
                                          .AcquireTokenInteractive(s_scopes)
                                          .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.SelectAccount, false, directToAdfs))
                                          .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                                          .ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(0, 1);
            IAccount account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 1); // the assert calls GetAccounts
            Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache);

            Trace.WriteLine("Part 2 - Clear the cache");
            await pca.RemoveAsync(account).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(1, 2);
            Assert.IsFalse((await pca.GetAccountsAsync().ConfigureAwait(false)).Any());
            userCacheAccess.AssertAccessCounts(2, 2);
            Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache);

            Trace.WriteLine("Part 3 - Acquire a token interactively again, with login hint");
            result = await pca
                     .AcquireTokenInteractive(s_scopes)
                     .WithCustomWebUi(CreateSeleniumCustomWebUI(labResponse.User, Prompt.ForceLogin, true, directToAdfs))
                     .WithPrompt(Prompt.ForceLogin)
                     .WithLoginHint(labResponse.User.Upn)
                     .ExecuteAsync(new CancellationTokenSource(_interactiveAuthTimeout).Token)
                     .ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(2, 3);

            account = await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            userCacheAccess.AssertAccessCounts(3, 3);
            Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache);

            Trace.WriteLine("Part 4 - Acquire a token silently");
            result = await pca
                     .AcquireTokenSilent(s_scopes, account)
                     .ExecuteAsync(CancellationToken.None)
                     .ConfigureAwait(false);

            await MsalAssert.AssertSingleAccountAsync(labResponse, pca, result).ConfigureAwait(false);

            Assert.IsFalse(userCacheAccess.LastNotificationArgs.IsApplicationCache);

            return(result);
        }
        private async Task <AuthenticationResult> RunTestForUserAsync(LabResponse labResponse, string authority)
        {
            var cert = await s_secretProvider.GetCertificateWithPrivateMaterialAsync(
                CertificateName, KeyVaultInstance.MsalTeam).ConfigureAwait(false);

            IConfidentialClientApplication cca;
            string redirectUri = SeleniumWebUI.FindFreeLocalhostRedirectUri();

            cca = ConfidentialClientApplicationBuilder
                  .Create(ConfidentialClientID)
                  .WithAuthority(authority)
                  .WithCertificate(cert)
                  .WithRedirectUri(redirectUri)
                  .WithTestLogging()
                  .Build();

            var cacheAccess = (cca as ConfidentialClientApplication).UserTokenCache.RecordAccess();

            Trace.WriteLine("Part 1 - Call GetAuthorizationRequestUrl to figure out where to go ");
            var startUri = await cca
                           .GetAuthorizationRequestUrl(s_scopes)
                           .ExecuteAsync()
                           .ConfigureAwait(false);

            cacheAccess.AssertAccessCounts(0, 0);

            Trace.WriteLine("Part 2 - Use a browser to login and to capture the authorization code ");
            var seleniumUi = new SeleniumWebUI((driver) =>
            {
                Trace.WriteLine("Starting Selenium automation");
                driver.PerformLogin(labResponse.User, Prompt.SelectAccount, false, false);
            }, TestContext);

            CancellationTokenSource cts = new CancellationTokenSource(s_timeout);
            Uri authCodeUri             = await seleniumUi.AcquireAuthorizationCodeAsync(
                startUri,
                new Uri(redirectUri),
                cts.Token)
                                          .ConfigureAwait(false);

            var authorizationResult = AuthorizationResult.FromUri(authCodeUri.AbsoluteUri);

            Assert.AreEqual(AuthorizationStatus.Success, authorizationResult.Status);

            Trace.WriteLine("Part 3 - Get a token using the auth code, just like a website");
            var result = await cca.AcquireTokenByAuthorizationCode(s_scopes, authorizationResult.Code)
                         .ExecuteAsync()
                         .ConfigureAwait(false);

            cacheAccess.AssertAccessCounts(0, 1);
            Assert.AreEqual(
                result.Account.HomeAccountId.Identifier,
                cacheAccess.LastAfterAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(
                result.Account.HomeAccountId.Identifier,
                cacheAccess.LastBeforeAccessNotificationArgs.SuggestedCacheKey);
            Assert.AreEqual(
                result.Account.HomeAccountId.Identifier,
                cacheAccess.LastBeforeWriteNotificationArgs.SuggestedCacheKey);

            return(result);
        }