public async Task <AuthorizationResult> AcquireAuthorizationAsync(
            Uri authorizationUri,
            Uri redirectUri,
            RequestContext requestContext,
            CancellationToken cancellationToken)
        {
            try
            {
                var authCodeUri = await InterceptAuthorizationUriAsync(
                    authorizationUri,
                    redirectUri,
                    cancellationToken)
                                  .ConfigureAwait(true);

                if (!authCodeUri.Authority.Equals(redirectUri.Authority, StringComparison.OrdinalIgnoreCase) ||
                    !authCodeUri.AbsolutePath.Equals(redirectUri.AbsolutePath))
                {
                    throw new MsalClientException(
                              MsalError.LoopbackResponseUriMismatch,
                              MsalErrorMessage.RedirectUriMismatch(
                                  authCodeUri.AbsolutePath,
                                  redirectUri.AbsolutePath));
                }

                return(AuthorizationResult.FromUri(authCodeUri.OriginalString));
            }
            catch (System.Net.HttpListenerException) // sometimes this exception sneaks out (see issue 1773)
            {
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
        private static void ValidateB2CLoginAuthority(MockHttpAndServiceBundle harness, string authority)
        {
            var app = PublicClientApplicationBuilder
                      .Create(TestConstants.ClientId)
                      .WithB2CAuthority(authority)
                      .WithHttpManager(harness.HttpManager)
                      .BuildConcrete();

            var ui = new MockWebUI()
            {
                MockResult = AuthorizationResult.FromUri(authority + "?code=some-code")
            };

            MsalMockHelpers.ConfigureMockWebUI(app.ServiceBundle.PlatformProxy, ui);
            harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(authority);
            harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority);

            var result = app
                         .AcquireTokenInteractive(TestConstants.s_scope)
                         .ExecuteAsync(CancellationToken.None)
                         .Result;

            Assert.IsNotNull(result);
            Assert.IsNotNull(result.Account);
        }
        public void PKeyAuthSuccsesResponseTest()
        {
            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();

                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                                              .WithHttpManager(harness.HttpManager)
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                //Initiates PKeyAuth challenge which will trigger an additional request sent to AAD to satisfy the PKeyAuth challenge
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreatePKeyAuthChallengeResponse()
                });
                harness.HttpManager.AddMockHandler(CreateTokenResponseHttpHandlerWithPKeyAuthValidation());

                AuthenticationResult result = app
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .Result;
            }
        }
        private bool CheckForClosingUrl(Uri url)
        {
            bool readyToClose = false;

            if (url.Authority.Equals(_desiredCallbackUri.Authority, StringComparison.OrdinalIgnoreCase) &&
                url.AbsolutePath.Equals(_desiredCallbackUri.AbsolutePath))
            {
                RequestContext.Logger.Info("Redirect Uri was reached. Stopping webview navigation...");
                Result       = AuthorizationResult.FromUri(url.OriginalString);
                readyToClose = true;
            }

            if (!readyToClose && !url.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
                !url.AbsoluteUri.Equals("about:blank", StringComparison.OrdinalIgnoreCase) && !url.Scheme.Equals("javascript", StringComparison.OrdinalIgnoreCase))
            {
                RequestContext.Logger.Error(string.Format(CultureInfo.InvariantCulture,
                                                          "Redirection to non-HTTPS scheme ({0}) found! Webview will fail...", url.Scheme));
                Result = AuthorizationResult.FromStatus(
                    AuthorizationStatus.ErrorHttp,
                    MsalError.NonHttpsRedirectNotSupported,
                    MsalErrorMessage.NonHttpsRedirectNotSupported);
                readyToClose = true;
            }

            if (readyToClose)
            {
                StopWebBrowser();
                // in this handler object could be already disposed, so it should be the last method
                OnClosingUrl();
            }

            return(readyToClose);
        }
示例#5
0
        public static bool ContinueAuthentication(string url, Core.ICoreLogger logger)
        {
            if (s_returnedUriReady == null)
            {
                bool containsBrokerSubString = url.Contains(iOSBrokerConstants.IdentifyiOSBrokerFromResponseUrl);

                logger?.Warning(
                    "Not expecting navigation to come back to WebviewBase. " +
                    "This can indicate  a badly setup OpenUrl hook " +
                    "where SetBrokerContinuationEventArgs is not called.");

                logger?.WarningPii(
                    $"Url: {url} is broker url? {containsBrokerSubString}",
                    $"Is broker url? {containsBrokerSubString}");

                return(false);
            }

            s_authorizationResult = AuthorizationResult.FromUri(url);
            logger?.Verbose("Response url parsed and the result is " + s_authorizationResult.Status);

            s_returnedUriReady.Release();

            return(true);
        }
        public void B2CAcquireTokenWithValidateAuthorityTrueTest()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(TestConstants.B2CLoginAuthority), true)
                                              .WithHttpManager(httpManager)
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority);
                httpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.B2CLoginAuthority);

                AuthenticationResult result = app
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .Result;

                Assert.IsNotNull(result);
                Assert.IsNotNull(result.Account);
            }
        }
示例#7
0
        public async Task DoNotCallPlatformProxyAsync()
        {
            // Arrange
            using (var harness = new MockHttpAndServiceBundle())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                var mockProxy = new MockProxy();
                var app       = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                                .WithHttpManager(harness.HttpManager)
                                .WithPlatformProxy(mockProxy)
                                .WithRedirectUri("http://localhost")
                                .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);

                // Act
                await app
                .AcquireTokenInteractive(TestConstants.s_scope)
                .ExecuteAsync()
                .ConfigureAwait(false);

                // Assert - NoDeviceIdProxy would fail if InternalGetDeviceId is called
                Assert.IsFalse(mockProxy.InternalDeviceIdWasCalled);
            }
        }
        private void RunCacheFormatValidation(MockHttpAndServiceBundle harness)
        {
            PublicClientApplication app = PublicClientApplicationBuilder
                                          .Create(_clientId)
                                          .WithAuthority(new Uri(_requestAuthority), true)
                                          .WithHttpManager(harness.HttpManager)
                                          .BuildConcrete();

            app.ServiceBundle.ConfigureMockWebUI(
                AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

            harness.HttpManager.AddMockHandler(new MockHttpMessageHandler
            {
                ExpectedMethod  = HttpMethod.Post,
                ResponseMessage = MockHelpers.CreateSuccessResponseMessage(_tokenResponse)
            });

            AuthenticationResult result = app
                                          .AcquireTokenInteractive(TestConstants.s_scope)
                                          .ExecuteAsync(CancellationToken.None)
                                          .Result;

            Assert.IsNotNull(result);

            ValidateAt(app.UserTokenCacheInternal);
            ValidateRt(app.UserTokenCacheInternal);
            ValidateIdToken(app.UserTokenCacheInternal);
            ValidateAccount(app.UserTokenCacheInternal);
        }
示例#9
0
        private async Task InteractiveAsync(PublicClientApplication app, ServerTokenResponse serverTokenResponse)
        {
            if (serverTokenResponse == ServerTokenResponse.ErrorClientMismatch)
            {
                throw new NotImplementedException("test error");
            }

            if (!_instanceAndEndpointRequestPerformed)
            {
                _instanceAndEndpointRequestPerformed = true;

                _harness.HttpManager.AddInstanceDiscoveryMockHandler();
                _harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityUtidTenant);
            }

            MsalMockHelpers.ConfigureMockWebUI(
                app.ServiceBundle.PlatformProxy,
                AuthorizationResult.FromUri(MsalTestConstants.B2CLoginAuthority + "?code=some-code"));

            _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                MsalTestConstants.AuthorityUtidTenant,
                foci: serverTokenResponse == ServerTokenResponse.FociToken);

            // Acquire token interactively for A
            AuthenticationResult result = await app.AcquireTokenInteractive(MsalTestConstants.Scope).ExecuteAsync(CancellationToken.None).ConfigureAwait(false);

            Assert.IsNotNull(result.Account);
            AssertAppMetadata(app, serverTokenResponse == ServerTokenResponse.FociToken);
        }
示例#10
0
        private bool CheckForEndUrl(Uri url)
        {
            bool readyToClose = false;

            if (url.Authority.Equals(_endUri.Authority, StringComparison.OrdinalIgnoreCase) &&
                url.AbsolutePath.Equals(_endUri.AbsolutePath))
            {
                _logger.Info("Redirect Uri was reached. Stopping webview navigation...");
                _result      = AuthorizationResult.FromUri(url.OriginalString);
                readyToClose = true;
            }

            if (!readyToClose &&
                !url.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) &&
                !url.AbsoluteUri.Equals("about:blank", StringComparison.OrdinalIgnoreCase) &&
                !url.Scheme.Equals("javascript", StringComparison.OrdinalIgnoreCase))
            {
                _logger.Error($"Redirection to non-HTTPS scheme ({url.Scheme}) found! Webview will fail...");

                _result = AuthorizationResult.FromStatus(
                    AuthorizationStatus.ErrorHttp,
                    MsalError.NonHttpsRedirectNotSupported,
                    MsalErrorMessage.NonHttpsRedirectNotSupported);

                readyToClose = true;
            }

            if (readyToClose)
            {
                // This should close the dialog
                DialogResult = DialogResult.OK;
            }

            return(readyToClose);
        }
示例#11
0
        public async Task B2CAcquireTokenWithValidateAuthorityTrueAndRandomAuthorityTest_Async()
        {
            using (var harness = base.CreateTestHarness())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(TestConstants.B2CCustomDomain), true)
                                              .WithHttpManager(harness.HttpManager)
                                              .WithCachePartitioningAsserts(harness.ServiceBundle.PlatformProxy)
                                              .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.B2CCustomDomain);

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

                Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);

                await app.AcquireTokenSilent(TestConstants.s_scope, result.Account).ExecuteAsync().ConfigureAwait(false);

                Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
            }
        }
示例#12
0
        [WorkItem(1418)] // test for bug https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1418
        public async Task VerifyAuthorizationResult_NoErrorDescription_Async()
        {
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                MockWebUI webUi = new MockWebUI()
                {
                    // error code and error description is empty string (not null)
                    MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?error=some_error&error_description= "),
                };

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false));

                InteractiveRequest request = new InteractiveRequest(
                    harness.ServiceBundle,
                    parameters,
                    new AcquireTokenInteractiveParameters(),
                    webUi);

                var ex = await AssertException.TaskThrowsAsync <MsalServiceException>(
                    () => request.ExecuteAsync(CancellationToken.None))
                         .ConfigureAwait(false);

                Assert.AreEqual("some_error", ex.ErrorCode);
                Assert.AreEqual(InteractiveRequest.UnknownError, ex.Message);
            }
        }
示例#13
0
        public async Task ClaimsAndClientCapabilities_AreMerged_And_AreSentTo_AuthorizationEndpoint_And_TokenEndpoint_Async()
        {
            // Arrange
            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();

                var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                          .WithHttpManager(harness.HttpManager)
                          .WithClientCapabilities(TestConstants.ClientCapabilities)
                          .WithTelemetry(new TraceTelemetryConfig())
                          .BuildConcrete();

                var mockUi =
                    app.ServiceBundle.ConfigureMockWebUI(
                        AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                mockUi.QueryParamsToValidate = new Dictionary <string, string> {
                    { OAuth2Parameter.Claims,
                      TestConstants.ClientCapabilitiesAndClaimsJson }
                };

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.AuthorityCommonTenant,
                    bodyParameters: mockUi.QueryParamsToValidate);

                AuthenticationResult result = await app
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .WithClaims(TestConstants.Claims)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                Assert.IsNotNull(result.Account);
            }
        }
示例#14
0
        private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult)
        {
            AuthorizationResult result;

            switch (webAuthenticationResult.ResponseStatus)
            {
            case WebAuthenticationStatus.Success:
                result = AuthorizationResult.FromUri(webAuthenticationResult.ResponseData);
                break;

            case WebAuthenticationStatus.ErrorHttp:
                result      = AuthorizationResult.FromStatus(AuthorizationStatus.ErrorHttp);
                result.Code = webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.InvariantCulture);
                break;

            case WebAuthenticationStatus.UserCancel:
                result = AuthorizationResult.FromStatus(AuthorizationStatus.UserCancel);
                break;

            default:
                result = AuthorizationResult.FromStatus(AuthorizationStatus.UnknownError);
                break;
            }

            return(result);
        }
示例#15
0
        public async Task BrokerInteractiveRequestBrokerRequiredTestAsync()
        {
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                MockWebUI ui = new MockWebUI()
                {
                    // When the auth code is returned from the authorization server prefixed with msauth://
                    // this means the user who logged requires cert based auth and broker
                    MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?code=msauth://some-code")
                };

                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                harness.ServiceBundle.PlatformProxy.SetBrokerForTest(CreateMockBroker());

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false));
                parameters.IsBrokerEnabled = false;

                InteractiveRequest request = new InteractiveRequest(
                    harness.ServiceBundle,
                    parameters,
                    new AcquireTokenInteractiveParameters(),
                    ui);

                AuthenticationResult result = await request.RunAsync(CancellationToken.None).ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("access-token", result.AccessToken);
            }
        }
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(
            Uri authorizationUri,
            Uri redirectUri,
            RequestContext requestContext,
            CancellationToken cancellationToken)
        {
            var authCodeUri = await InterceptAuthorizationUriAsync(
                authorizationUri,
                redirectUri,
                cancellationToken)
                              .ConfigureAwait(true);


            if (!authCodeUri.Authority.Equals(redirectUri.Authority, StringComparison.OrdinalIgnoreCase) ||
                !authCodeUri.AbsolutePath.Equals(redirectUri.AbsolutePath))
            {
                throw new MsalClientException(
                          MsalError.LoopbackResponseUriMisatch,
                          MsalErrorMessage.RedirectUriMismatch(
                              authCodeUri.AbsolutePath,
                              redirectUri.AbsolutePath));
            }

            return(AuthorizationResult.FromUri(authCodeUri.OriginalString));
        }
        public async Task WithExtraQueryParamsAndClaimsAsync()
        {
            IDictionary <string, string> extraQueryParamsAndClaims =
                TestConstants.ExtraQueryParameters.ToDictionary(e => e.Key, e => e.Value);

            extraQueryParamsAndClaims.Add(OAuth2Parameter.Claims, TestConstants.Claims);

            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                var cache = new TokenCache(harness.ServiceBundle, false);

                var ui = new MockWebUI()
                {
                    MockResult            = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?code=some-code"),
                    QueryParamsToValidate = TestConstants.ExtraQueryParameters
                };
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui);

                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                var tokenResponseHandler = new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Post,
                    ExpectedQueryParams = TestConstants.ExtraQueryParameters,
                    ExpectedPostData    = new Dictionary <string, string>()
                    {
                        { OAuth2Parameter.Claims, TestConstants.Claims }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage()
                };
                harness.HttpManager.AddMockHandler(tokenResponseHandler);

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    cache,
                    extraQueryParameters: TestConstants.ExtraQueryParameters,
                    claims: TestConstants.Claims);

                parameters.RedirectUri = new Uri("some://uri");
                parameters.LoginHint   = TestConstants.DisplayableId;

                AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.SelectAccount,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                };

                var request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

                AuthenticationResult result = await request.RunAsync().ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllRefreshTokens().Count());
                Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(result.AccessToken, "some-access-token");
            }
        }
        public void FromUri_Onback_ReturnsCancel()
        {
            var authResult = AuthorizationResult.FromUri($"urn:ietf:wg:oauth:2.0:oob?error=access_denied&error_subcode=cancel&state=5f5c0853-8a53-48de-b47a-afd0c33301f90170c6b7-b956-4aab-b99b-0e6a067dad0b");

            Assert.AreEqual(AuthorizationStatus.UserCancel, authResult.Status);
            Assert.AreEqual(MsalError.AuthenticationCanceledError, authResult.Error);
        }
示例#19
0
        //Test for bug #1292 (https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1292)
        public void AuthorityCustomPortTest()
        {
            var customPortAuthority = "https://localhost:5215/common/";

            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler(customPortAuthority);

                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(customPortAuthority), false)
                                              .WithHttpManager(harness.HttpManager)
                                              .BuildConcrete();

                //Ensure that the PublicClientApplication init does not remove the port from the authority
                Assert.AreEqual(customPortAuthority, app.Authority);

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(customPortAuthority);
                harness.HttpManager.AddInstanceDiscoveryMockHandler(customPortAuthority);

                AuthenticationResult result = app
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .Result;

                //Ensure that acquiring a token does not remove the port from the authority
                Assert.AreEqual(customPortAuthority, app.Authority);
            }
        }
示例#20
0
        public async Task AcquireTokenInterative_WithValidCustomInstanceMetadata_Async()
        {
            string instanceMetadataJson = File.ReadAllText(
                ResourceHelper.GetTestResourceRelativePath("CustomInstanceMetadata.json"));

            using (var harness = CreateTestHarness())
            {
                // No instance discovery is made - it is important to not have this mock handler added
                // harness.HttpManager.AddInstanceDiscoveryMockHandler();

                PublicClientApplication app = PublicClientApplicationBuilder
                                              .Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri("https://login.windows.net/common/"), false)
                                              .WithInstanceDiscoveryMetadata(instanceMetadataJson)
                                              .WithHttpManager(harness.HttpManager)
                                              .BuildConcrete();

                app.ServiceBundle.ConfigureMockWebUI(
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));

                // the rest of the communication with AAD happens on the preferred_network alias, not on login.windows.net
                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);

                AuthenticationResult result = await app
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.IsNotNull(result.Account);
                Assert.AreEqual(TestConstants.UniqueId, result.UniqueId);
                Assert.AreEqual(TestConstants.CreateUserIdentifier(), result.Account.HomeAccountId.Identifier);
                Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username);
            }
        }
示例#21
0
        public async Task TestAccountAcrossMultipleClientIdsAsync()
        {
            using (var _harness = CreateTestHarness())
            {
                // Arrange
                PublicClientApplication app = PublicClientApplicationBuilder
                                              .Create(TestConstants.ClientId)
                                              .WithHttpManager(_harness.HttpManager)
                                              .BuildConcrete();

                Trace.WriteLine("Step 1 - call GetAccounts with empty cache - no accounts, no tokens");
                var cacheAccessRecorder1 = app.UserTokenCache.RecordAccess();
                var accounts             = await app.GetAccountsAsync().ConfigureAwait(false);

                Assert.IsFalse(cacheAccessRecorder1.LastBeforeAccessNotificationArgs.HasTokens);
                Assert.IsNull(cacheAccessRecorder1.LastBeforeWriteNotificationArgs);
                Assert.IsFalse(cacheAccessRecorder1.LastAfterAccessNotificationArgs.HasTokens);
                Assert.IsFalse(accounts.Any());

                Trace.WriteLine("Step 2 - call AcquireTokenInteractive - it will save new tokens in the cache");
                app.ServiceBundle.ConfigureMockWebUI(
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));
                _harness.HttpManager.AddInstanceDiscoveryMockHandler();
                _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost();
                var  cacheAccessRecorder2 = app.UserTokenCache.RecordAccess();
                Guid correlationId        = Guid.NewGuid();
                await app
                .AcquireTokenInteractive(TestConstants.s_scope)
                .WithCorrelationId(correlationId)
                .ExecuteAsync()
                .ConfigureAwait(false);

                Assert.IsFalse(cacheAccessRecorder2.LastBeforeAccessNotificationArgs.HasTokens);
                Assert.IsFalse(cacheAccessRecorder2.LastBeforeWriteNotificationArgs.HasTokens);
                Assert.IsTrue(cacheAccessRecorder2.LastAfterAccessNotificationArgs.HasTokens);

                Assert.AreEqual(correlationId, cacheAccessRecorder2.LastBeforeAccessNotificationArgs.CorrelationId);
                Assert.AreEqual(correlationId, cacheAccessRecorder2.LastBeforeWriteNotificationArgs.CorrelationId);
                Assert.AreEqual(correlationId, cacheAccessRecorder2.LastAfterAccessNotificationArgs.CorrelationId);

                Trace.WriteLine("Step 3 - call GetAccounts - now with 1 account");
                var cacheAccessRecorder3 = app.UserTokenCache.RecordAccess();
                accounts = await app.GetAccountsAsync().ConfigureAwait(false);

                Assert.IsTrue(cacheAccessRecorder3.LastBeforeAccessNotificationArgs.HasTokens);
                Assert.IsNull(cacheAccessRecorder3.LastBeforeWriteNotificationArgs);
                Assert.IsTrue(cacheAccessRecorder3.LastAfterAccessNotificationArgs.HasTokens);
                Assert.IsTrue(accounts.Any());

                Trace.WriteLine("Step 4 - call RemoveAccounts - this will delete all the tokens");
                var cacheAccessRecorder4 = app.UserTokenCache.RecordAccess();
                await app.RemoveAsync(accounts.Single()).ConfigureAwait(false);

                Assert.IsTrue(cacheAccessRecorder4.LastBeforeAccessNotificationArgs.HasTokens);
                Assert.IsTrue(cacheAccessRecorder4.LastBeforeWriteNotificationArgs.HasTokens);
                Assert.IsFalse(cacheAccessRecorder4.LastAfterAccessNotificationArgs.HasTokens);
            }
        }
        /// <summary>
        /// Configures a web ui that returns a succesfull result
        /// </summary>
        public static void ConfigureMockWebUI(IPublicClientApplication pca)
        {
            var       app   = pca as PublicClientApplication;
            MockWebUI webUi = new MockWebUI
            {
                MockResult = AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")
            };

            ConfigureMockWebUI(app.ServiceBundle.PlatformProxy, webUi);
        }
示例#23
0
        public static bool ContinueAuthentication(string url)
        {
            if (returnedUriReady == null)
            {
                return(false);
            }

            authorizationResult = AuthorizationResult.FromUri(url);
            returnedUriReady.Release();

            return(true);
        }
        private static AuthorizationResult ProcessFromSystemWebview(int requestCode, Result resultCode, Intent data)
        {
            switch ((int)resultCode)
            {
            case AndroidConstants.AuthCodeReceived:
                return(AuthorizationResult.FromUri(data.GetStringExtra("com.microsoft.identity.client.finalUrl")));

            case AndroidConstants.Cancel:
                return(AuthorizationResult.FromStatus(AuthorizationStatus.UserCancel));

            default:
                return(AuthorizationResult.FromStatus(AuthorizationStatus.UnknownError));
            }
        }
        private static AuthorizationResult ProcessFromEmbeddedWebview(int requestCode, Result resultCode, Intent data)
        {
            switch ((int)resultCode)
            {
            case (int)Result.Ok:
                return(AuthorizationResult.FromUri(data.GetStringExtra("ReturnedUrl")));

            case (int)Result.Canceled:
                return(AuthorizationResult.FromStatus(AuthorizationStatus.UserCancel));

            default:
                return(AuthorizationResult.FromStatus(AuthorizationStatus.UnknownError));
            }
        }
        /// <summary>
        /// Configures a web ui that returns a succesfull result
        /// </summary>
        public static void ConfigureMockWebUI(
            this IServiceBundle serviceBundle,
            IWebUI webUi = null)
        {
            if (webUi == null)
            {
                webUi = new MockWebUI
                {
                    MockResult = AuthorizationResult.FromUri(serviceBundle.Config.RedirectUri + "?code=some-code")
                };
            }

            ConfigureWebUiFactory(serviceBundle, webUi);
        }
        public async Task PKeyAuthSuccsesWithExtraQueryParamsResponseTestAsync()
        {
            using (var harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();

                var builder = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                              .WithAuthority("https://login.microsoftonline.com/common")
                              .WithHttpManager(harness.HttpManager);
                builder.Config.DeviceAuthManagerForTest = Substitute.For <IDeviceAuthManager>();
                Uri actualUri = null;
                builder.Config.DeviceAuthManagerForTest.TryCreateDeviceAuthChallengeResponseAsync(
                    Arg.Any <HttpResponseHeaders>(),
                    Arg.Any <Uri>(),
                    out Arg.Any <string>())
                .Returns(x => {
                    x[2]      = TestConstants.PKeyAuthResponse;
                    actualUri = (Uri)x[1];
                    return(true);
                });


                var pca = builder.BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    pca.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(pca.AppConfig.RedirectUri + "?code=some-code"));

                //Initiates PKeyAuth challenge which will trigger an additional request sent to AAD to satisfy the PKeyAuth challenge
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreatePKeyAuthChallengeResponse()
                });
                harness.HttpManager.AddMockHandler(CreateTokenResponseHttpHandlerWithPKeyAuthValidation());

                AuthenticationResult result = await pca
                                              .AcquireTokenInteractive(TestConstants.s_scope)
                                              .WithExtraQueryParameters("qp1=v1")
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                // Assert that the endpoint sent to the device auth manager doesn not have query params
                //await builder.Config.DeviceAuthManagerForTest.Received()
                //    .TryCreateDeviceAuthChallengeResponseAsync(Arg.Any<HttpResponseHeaders>(), "foo", Arg.Any<string>());
                Assert.AreEqual("https://login.microsoftonline.com/common/oauth2/v2.0/token", actualUri.AbsoluteUri);
            }
        }
示例#28
0
        public static bool ContinueAuthentication(string url)
        {
            if (returnedUriReady == null)
            {
                return(false);
            }

            viewController.InvokeOnMainThread(() =>
            {
                authorizationResult = AuthorizationResult.FromUri(url);
                returnedUriReady.Release();
            });

            return(true);
        }
        private static string GetMessageToShowInBroswerAfterAuth(Uri authCodeUri)
        {
            // Parse the uri to understand if an error was returned. This is done just to show the user a nice error message in the browser.
            var authorizationResult = AuthorizationResult.FromUri(authCodeUri.OriginalString);

            if (!string.IsNullOrEmpty(authorizationResult.Error))
            {
                return(string.Format(
                           CultureInfo.InvariantCulture,
                           CloseWindowFailureHtml,
                           authorizationResult.Error,
                           authorizationResult.ErrorDescription));
            }

            return(CloseWindowSuccessHtml);
        }
        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();

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

            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);

            return(result);
        }