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");
            }
        }
        [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= "),
                };
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi);

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

                var request = new InteractiveRequest(
                    parameters,
                    new AcquireTokenInteractiveParameters());

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

                Assert.AreEqual("some_error", ex.ErrorCode);
                Assert.AreEqual("Unknown error", ex.Message);
            }
        }
        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);
            }
        }
Esempio n. 4
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 = MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    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);
            }
        }
Esempio n. 5
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);
            }
        }
        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);
        }
Esempio n. 7
0
        public async Task AfterAccess_Is_Called_When_BeforeAceess_Throws_Async()
        {
            using (var harness = CreateTestHarness())
            {
                var pca = PublicClientApplicationBuilder
                          .Create(TestConstants.ClientId)
                          .WithHttpManager(harness.HttpManager)
                          .BuildConcrete();

                var tokenCacheHelper = new TokenCacheHelper();
                tokenCacheHelper.PopulateCache(pca.UserTokenCacheInternal.Accessor, addSecondAt: false);
                var account = (await pca.GetAccountsAsync().ConfigureAwait(false)).First();

                // All these actions trigger a reloading of the cache
                await RunAfterAccessFailureAsync(pca, () => pca.GetAccountsAsync()).ConfigureAwait(false);
                await RunAfterAccessFailureAsync(pca,
                                                 () => pca.AcquireTokenSilent(new[] { "User.Read" }, account).ExecuteAsync())
                .ConfigureAwait(false);
                await RunAfterAccessFailureAsync(pca, () => pca.RemoveAsync(account)).ConfigureAwait(false);

                // AcquireTokenInteractive will save a token to the cache, but needs more setup
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);

                MsalMockHelpers.ConfigureMockWebUI(pca);
                await RunAfterAccessFailureAsync(pca, () =>
                                                 pca.AcquireTokenInteractive(new[] { "User.Read" }).ExecuteAsync())
                .ConfigureAwait(false);
            }
        }
Esempio n. 8
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);
            }
        }
Esempio n. 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);
        }
        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;
            }
        }
Esempio n. 11
0
        private async Task RunCacheFormatValidationAsync(MockHttpAndServiceBundle harness)
        {
            PublicClientApplication app = PublicClientApplicationBuilder
                                          .Create(_clientId)
                                          .WithAuthority(new Uri(_requestAuthority), true)
                                          .WithHttpManager(harness.HttpManager)
                                          .WithTelemetry(new TraceTelemetryConfig())
                                          .BuildConcrete();

            MsalMockHelpers.ConfigureMockWebUI(
                app.ServiceBundle.PlatformProxy,
                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);

            await ValidateAtAsync(app.UserTokenCacheInternal).ConfigureAwait(false);
            await ValidateRtAsync(app.UserTokenCacheInternal).ConfigureAwait(false);
            await ValidateIdTokenAsync(app.UserTokenCacheInternal).ConfigureAwait(false);
            await ValidateAccountAsync(app.UserTokenCacheInternal).ConfigureAwait(false);
        }
Esempio n. 12
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);
            }
        }
Esempio n. 13
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");
                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));
                _harness.HttpManager.AddInstanceDiscoveryMockHandler();
                _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost();
                var cacheAccessRecorder2 = app.UserTokenCache.RecordAccess();

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

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

                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);
            }
        }
        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);
            }
        }
        private async Task ExecuteTestAsync(
            bool withTokenRequest,
            Action <ICustomWebUi> customizeWebUiBehavior,
            Func <InteractiveRequest, Task> executionBehavior)
        {
            var customWebUi = Substitute.For <ICustomWebUi>();

            customizeWebUiBehavior(customWebUi);

            using (var harness = CreateTestHarness())
            {
                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                if (withTokenRequest)
                {
                    harness.HttpManager.AddMockHandler(
                        new MockHttpMessageHandler
                    {
                        ExpectedMethod  = HttpMethod.Post,
                        ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage()
                    });
                }

                var parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false));
                parameters.RedirectUri = new Uri(ExpectedRedirectUri);
                parameters.LoginHint   = TestConstants.DisplayableId;
                var interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.ForceLogin,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                    CustomWebUi          = customWebUi
                };

                var ui = new CustomWebUiHandler(customWebUi);
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui);

                var request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

                await executionBehavior(request).ConfigureAwait(false);
            }
        }
        public void DuplicateQueryParameterErrorTest()
        {
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityHomeTenant);

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false),
                    extraQueryParameters: new Dictionary <string, string> {
                    { "extra", "qp" }, { "prompt", "login" }
                });
                parameters.RedirectUri = new Uri("some://uri");
                parameters.LoginHint   = TestConstants.DisplayableId;
                AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.ForceLogin,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                };

                var request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, new MockWebUI());

                try
                {
                    request.RunAsync().Wait();
                    Assert.Fail("MsalException should be thrown here");
                }
                catch (Exception exc)
                {
                    Assert.IsTrue(exc.InnerException is MsalException);
                    Assert.AreEqual(
                        MsalError.DuplicateQueryParameterError,
                        ((MsalException)exc.InnerException).ErrorCode);
                }
            }
        }
        private void ValidateOathClient(HttpResponseMessage httpResponseMessage, Action <Exception> validationHandler)
        {
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                harness.HttpManager.AddInstanceDiscoveryMockHandler();
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = httpResponseMessage
                });

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false));
                parameters.RedirectUri = new Uri("some://uri");
                parameters.LoginHint   = TestConstants.DisplayableId;
                AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.SelectAccount,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                };
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, new MockWebUI());

                var request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

                try
                {
                    request.RunAsync().Wait();
                    Assert.Fail("MsalException should have been thrown here");
                }
                catch (Exception exc)
                {
                    validationHandler(exc);
                }
            }
        }
Esempio n. 18
0
        public async Task CustomInstanceDiscoveryMetadataUri_Async()
        {
            using (var harness = CreateTestHarness())
            {
                var customMetadataUri = new Uri("https://custom.instance.discovery.uri");
                var customAuthrority  = "https://my.custom.authority/common/";

                harness.HttpManager.AddInstanceDiscoveryMockHandler(
                    customAuthrority,
                    customMetadataUri,
                    TestConstants.DiscoveryJsonResponse.Replace("login.microsoftonline.com", "my.custom.authority"));

                PublicClientApplication app = PublicClientApplicationBuilder
                                              .Create(TestConstants.ClientId)
                                              .WithAuthority(customAuthrority, false)
                                              .WithInstanceDiscoveryMetadata(customMetadataUri)
                                              .WithHttpManager(harness.HttpManager)
                                              .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    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.AddMockHandlerForTenantEndpointDiscovery(customAuthrority);
                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(customAuthrority);

                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);
            }
        }
Esempio n. 19
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)
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    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.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant);
                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);
            }
        }
        public async Task B2CAcquireTokenWithResetPasswordTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithB2CAuthority(TestConstants.B2CLoginAuthority)
                                              .WithHttpManager(httpManager)
                                              .WithDebugLoggingCallback(logLevel: LogLevel.Verbose)
                                              .BuildConcrete();

                // Interactive call and user wants to reset password
                var ui = new MockWebUI()
                {
                    MockResult = AuthorizationResult.FromUri(TestConstants.B2CLoginAuthority +
                                                             "?error=access_denied&error_description=AADB2C90091%3a+The+user+has+cancelled+entering+self-asserted+information.")
                };

                httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority);
                MsalMockHelpers.ConfigureMockWebUI(app.ServiceBundle.PlatformProxy, ui);

                try
                {
                    AuthenticationResult result = await app
                                                  .AcquireTokenInteractive(TestConstants.s_scope)
                                                  .ExecuteAsync(CancellationToken.None)
                                                  .ConfigureAwait(false);
                }
                catch (MsalServiceException exc)
                {
                    Assert.IsNotNull(exc);
                    Assert.AreEqual("access_denied", exc.ErrorCode);
                    Assert.AreEqual("AADB2C90091: The user has cancelled entering self-asserted information.", exc.Message);
                    return;
                }
            }

            Assert.Fail("Should not reach here. Exception was not thrown.");
        }
        public async Task B2C_NoScopes_NoAccessToken_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(TestConstants.B2CLoginAuthority), true)
                                              .WithHttpManager(httpManager)
                                              .BuildConcrete();

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

                // Arrange 1 - interactive call with 0 scopes
                httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority);
                httpManager.AddSuccessTokenResponseMockHandlerForPost(
                    TestConstants.B2CLoginAuthority,
                    responseMessage: MockHelpers.CreateSuccessResponseMessage(MockHelpers.B2CTokenResponseWithoutAT));

                // Act
                AuthenticationResult result = await app
                                              .AcquireTokenInteractive(null) // no scopes -> no Access Token!
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                // Assert
                AssertNoAccessToken(result);
                Assert.AreEqual(0, httpManager.QueueSize);

                var ex = await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() =>
                                                                                         app.AcquireTokenSilent(null, result.Account).ExecuteAsync()
                                                                                         ).ConfigureAwait(false);

                Assert.AreEqual(MsalError.ScopesRequired, ex.ErrorCode);
                Assert.AreEqual(UiRequiredExceptionClassification.AcquireTokenSilentFailed, ex.Classification);
            }
        }
        public void RunCacheFormatValidation()
        {
            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                TestInitialize(httpManager);

                PublicClientApplication app = new PublicClientApplication(serviceBundle, ClientId, RequestAuthority);
                MockWebUI ui = new MockWebUI()
                {
                    MockResult = new AuthorizationResult(AuthorizationStatus.Success,
                                                         MsalTestConstants.AuthorityHomeTenant + "?code=some-code")
                };
                MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success,
                                                                           app.RedirectUri + "?code=some-code"));

                //add mock response for tenant endpoint discovery
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    Method          = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityHomeTenant)
                });
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    Method          = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessResponseMessage(TokenResponse)
                });

                AuthenticationResult result = app.AcquireTokenAsync(MsalTestConstants.Scope).Result;
                Assert.IsNotNull(result);

                ValidateAt(app.UserTokenCache);
                ValidateRt(app.UserTokenCache);
                ValidateIdToken(app.UserTokenCache);
                ValidateAccount(app.UserTokenCache);
            }
        }
Esempio n. 23
0
        public void UnifiedCache_RemoveAccountIsApplicationSpecific()
        {
            byte[] data = null;

            using (var httpManager = new MockHttpManager())
            {
                // login to app
                var app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                          .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                          .WithHttpManager(httpManager)
                          .WithTelemetry(new TraceTelemetryConfig())
                          .BuildConcrete();

                app.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) =>
                {
                    args.TokenCache.DeserializeMsalV3(data);
                });
                app.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) =>
                {
                    data = args.TokenCache.SerializeMsalV3();
                });

                httpManager.AddInstanceDiscoveryMockHandler();

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

                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant);
                httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority);

                AuthenticationResult result = app
                                              .AcquireTokenInteractive(MsalTestConstants.Scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .Result;

                Assert.IsNotNull(result);

                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccounts().Count());
                Assert.AreEqual(1, app.GetAccountsAsync().Result.Count());

                // login to app1 with same credentials

                var app1 = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId2)
                           .WithHttpManager(httpManager)
                           .WithTelemetry(new TraceTelemetryConfig())
                           .WithAuthority(
                    new Uri(ClientApplicationBase.DefaultAuthority),
                    true).BuildConcrete();

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

                app1.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) =>
                {
                    args.TokenCache.DeserializeMsalV3(data);
                });
                app1.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) =>
                {
                    data = args.TokenCache.SerializeMsalV3();
                });

                httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority);

                result = app1
                         .AcquireTokenInteractive(MsalTestConstants.Scope)
                         .ExecuteAsync(CancellationToken.None)
                         .Result;

                Assert.IsNotNull(result);

                // make sure that only one account cache entity was created
                Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count());

                Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
                Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllIdTokens().Count());
                Assert.AreEqual(1, app1.UserTokenCacheInternal.Accessor.GetAllAccounts().Count());

                // remove account from app
                app.RemoveAsync(app.GetAccountsAsync().Result.First()).Wait();

                // make sure account removed from app
                Assert.AreEqual(0, app.GetAccountsAsync().Result.Count());

                // make sure account Not removed from app1
                Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count());
            }
        }
Esempio n. 24
0
        public void UnifiedCache_MsalStoresToAndReadRtFromAdalCache()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                          .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                          .WithHttpManager(httpManager)
                          .WithTelemetry(new TraceTelemetryConfig())
                          .WithUserTokenLegacyCachePersistenceForTest(
                    new TestLegacyCachePersistance())
                          .BuildConcrete();

                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"));
                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant);
                httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority);

                AuthenticationResult result = app.AcquireTokenInteractive(MsalTestConstants.Scope).ExecuteAsync(CancellationToken.None).Result;
                Assert.IsNotNull(result);

                // make sure Msal stored RT in Adal cache
                IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCacheDictionary =
                    AdalCacheOperations.Deserialize(app.ServiceBundle.DefaultLogger, app.UserTokenCacheInternal.LegacyPersistence.LoadCache());

                Assert.IsTrue(adalCacheDictionary.Count == 1);

                var requestContext = new RequestContext(app.ServiceBundle, Guid.NewGuid());
                var accounts       = app.UserTokenCacheInternal.GetAccountsAsync(
                    MsalTestConstants.AuthorityCommonTenant, requestContext).Result;
                foreach (IAccount account in accounts)
                {
                    app.UserTokenCacheInternal.RemoveMsalAccountWithNoLocks(account, requestContext);
                }

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod   = HttpMethod.Post,
                    ExpectedPostData = new Dictionary <string, string>()
                    {
                        { "grant_type", "refresh_token" }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        MsalTestConstants.UniqueId,
                        MsalTestConstants.DisplayableId,
                        MsalTestConstants.Scope.ToArray())
                });

                // Using RT from Adal cache for silent call
                AuthenticationResult result1 = app
                                               .AcquireTokenSilent(MsalTestConstants.Scope, result.Account)
                                               .WithAuthority(MsalTestConstants.AuthorityCommonTenant)
                                               .WithForceRefresh(false)
                                               .ExecuteAsync(CancellationToken.None)
                                               .Result;

                Assert.IsNotNull(result1);
            }
        }
        private async Task <(HttpRequestMessage HttpRequest, Guid Correlationid)> RunAcquireTokenInteractiveAsync(
            AcquireTokenInteractiveOutcome outcome)
        {
            MockHttpMessageHandler tokenRequestHandler = null;
            Guid correlationId = default;

            switch (outcome)
            {
            case AcquireTokenInteractiveOutcome.Success:
                MsalMockHelpers.ConfigureMockWebUI(
                    _app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(_app.AppConfig.RedirectUri + "?code=some-code"));
                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost();
                var authResult = await _app
                                 .AcquireTokenInteractive(TestConstants.s_scope)
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenInteractiveOutcome.AuthorizationError:
                correlationId = Guid.NewGuid();

                var ui = Substitute.For <IWebUI>();
                ui.UpdateRedirectUri(Arg.Any <Uri>()).Returns(new Uri("http://localhost:1234"));
                ui.AcquireAuthorizationAsync(null, null, null, default).ThrowsForAnyArgs(
                    new MsalClientException("user_cancelled"));
                MsalMockHelpers.ConfigureMockWebUI(_app.ServiceBundle.PlatformProxy, ui);

                var ex = await AssertException.TaskThrowsAsync <MsalClientException>(() =>
                                                                                     _app
                                                                                     .AcquireTokenInteractive(TestConstants.s_scope)
                                                                                     .WithCorrelationId(correlationId)
                                                                                     .ExecuteAsync())
                         .ConfigureAwait(false);

                break;

            case AcquireTokenInteractiveOutcome.AADUnavailableError:
                correlationId = Guid.NewGuid();

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

                tokenRequestHandler = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout")
                };
                var tokenRequestHandler2 = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout")
                };

                // 2 of these are needed because MSAL has a "retry once" policy for 5xx errors
                _harness.HttpManager.AddMockHandler(tokenRequestHandler2);
                _harness.HttpManager.AddMockHandler(tokenRequestHandler);

                var serviceEx = await AssertException.TaskThrowsAsync <MsalServiceException>(() =>
                                                                                             _app
                                                                                             .AcquireTokenInteractive(TestConstants.s_scope)
                                                                                             .WithCorrelationId(correlationId)
                                                                                             .ExecuteAsync())
                                .ConfigureAwait(false);

                break;

            default:
                throw new NotImplementedException();
            }

            Assert.AreEqual(0, _harness.HttpManager.QueueSize);

            return(tokenRequestHandler?.ActualRequestMessage, correlationId);
        }
Esempio n. 26
0
        public async Task AuthorityMigrationTestAsync()
        {
            // make sure that for all network calls "preferred_cache" environment is used
            // (it is taken from metadata in instance discovery response),
            // except very first network call - instance discovery

            using (var httpManager = new MockHttpManager())
            {
                var authorityUri = new Uri(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "https://{0}/common",
                        TestConstants.ProductionNotPrefEnvironmentAlias));

                httpManager.AddInstanceDiscoveryMockHandler(authorityUri.AbsoluteUri);

                PublicClientApplication app = PublicClientApplicationBuilder
                                              .Create(TestConstants.ClientId)
                                              .WithAuthority(authorityUri, true)
                                              .WithHttpManager(httpManager)
                                              .WithUserTokenLegacyCachePersistenceForTest(new TestLegacyCachePersistance())
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .WithDebugLoggingCallback()
                                              .BuildConcrete();

                // mock for openId config request
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/common/v2.0/.well-known/openid-configuration",
                                                TestConstants.ProductionPrefNetworkEnvironment),
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(TestConstants.AuthorityHomeTenant)
                });

                // mock webUi authorization
                MsalMockHelpers.ConfigureMockWebUI(
                    app.ServiceBundle.PlatformProxy,
                    AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"), null, TestConstants.ProductionPrefNetworkEnvironment);

                // mock token request
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/home/oauth2/v2.0/token",
                                                TestConstants.ProductionPrefNetworkEnvironment),
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage()
                });

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

                // make sure that all cache entities are stored with "preferred_cache" environment
                // (it is taken from metadata in instance discovery response)
                await ValidateCacheEntitiesEnvironmentAsync(app.UserTokenCacheInternal, TestConstants.ProductionPrefCacheEnvironment).ConfigureAwait(false);

                // silent request targeting at, should return at from cache for any environment alias
                foreach (var envAlias in TestConstants.s_prodEnvAliases)
                {
                    result = await app
                             .AcquireTokenSilent(
                        TestConstants.s_scope,
                        app.GetAccountsAsync().Result.First())
                             .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, TestConstants.Utid))
                             .WithForceRefresh(false)
                             .ExecuteAsync(CancellationToken.None)
                             .ConfigureAwait(false);

                    Assert.IsNotNull(result);
                }

                // mock for openId config request for tenant specific authority
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/v2.0/.well-known/openid-configuration",
                                                TestConstants.ProductionPrefNetworkEnvironment, TestConstants.Utid),
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(TestConstants.AuthorityUtidTenant)
                });

                // silent request targeting rt should find rt in cache for authority with any environment alias
                foreach (var envAlias in TestConstants.s_prodEnvAliases)
                {
                    result = null;

                    httpManager.AddMockHandler(new MockHttpMessageHandler()
                    {
                        ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/oauth2/v2.0/token",
                                                    TestConstants.ProductionPrefNetworkEnvironment, TestConstants.Utid),
                        ExpectedMethod   = HttpMethod.Post,
                        ExpectedPostData = new Dictionary <string, string>()
                        {
                            { "grant_type", "refresh_token" }
                        },
                        // return not retriable status code
                        ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage()
                    });

                    try
                    {
                        result = await app
                                 .AcquireTokenSilent(
                            TestConstants.s_scopeForAnotherResource,
                            (await app.GetAccountsAsync().ConfigureAwait(false)).First())
                                 .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, TestConstants.Utid))
                                 .WithForceRefresh(false)
                                 .ExecuteAsync(CancellationToken.None).ConfigureAwait(false);
                    }
                    catch (MsalUiRequiredException)
                    {
                    }
                    catch (Exception)
                    {
                        Assert.Fail();
                    }

                    Assert.IsNull(result);
                }
            }
        }
Esempio n. 27
0
        public async Task TestSerializationViaAsync()
        {
            int numBeforeAccessCalls = 0;
            int numAfterAccessCalls  = 0;
            int numBeforeWriteCalls  = 0;

            byte[] serializedPayload = null;

            var sb = new StringBuilder();

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

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

                pca.UserTokenCache.SetBeforeAccessAsync(async args =>
                {
                    sb.Append("beforeaccess-");
                    numBeforeAccessCalls++;

                    // Task Delay is so that we have an await within the async callback and also to simulate
                    // some level of time that we did work.
                    await Task.Delay(10).ConfigureAwait(false);
                });
                pca.UserTokenCache.SetAfterAccessAsync(async args =>
                {
                    sb.Append("afteraccess-");
                    numAfterAccessCalls++;
                    serializedPayload = args.TokenCache.SerializeMsalV3();
                    await Task.Delay(10).ConfigureAwait(false);
                });
                pca.UserTokenCache.SetBeforeWriteAsync(async args =>
                {
                    sb.Append("beforewrite-");
                    numBeforeWriteCalls++;
                    await Task.Delay(10).ConfigureAwait(false);
                });

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

                harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant);
                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);

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

            Assert.AreEqual("beforeaccess-beforewrite-afteraccess-", sb.ToString());

            Assert.AreEqual(1, numBeforeAccessCalls);
            Assert.AreEqual(1, numAfterAccessCalls);
            Assert.AreEqual(1, numBeforeWriteCalls);

            Assert.IsNotNull(serializedPayload);
        }
Esempio n. 28
0
        public void AuthorityMigration_IntegrationTest()
        {
            // make sure that for all network calls "preferred_cache" environment is used
            // (it is taken from metadata in instance discovery response),
            // except very first network call - instance discovery

            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                TestInitialize(httpManager);

                PublicClientApplication app = new PublicClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId,
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "https://{0}/common",
                        MsalTestConstants.ProductionNotPrefEnvironmentAlias))
                {
                    UserTokenCache =
                    {
                        LegacyCachePersistence = new TestLegacyCachePersistance()
                    }
                };

                // mock for openId config request
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/common/v2.0/.well-known/openid-configuration",
                                        MsalTestConstants.ProductionPrefNetworkEnvironment),
                    Method          = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityHomeTenant)
                });

                // mock webUi authorization
                MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success,
                                                                           app.RedirectUri + "?code=some-code"), null, MsalTestConstants.ProductionPrefNetworkEnvironment);

                // mock token request
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/home/oauth2/v2.0/token",
                                        MsalTestConstants.ProductionPrefNetworkEnvironment),
                    Method          = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage()
                });

                AuthenticationResult result = app.AcquireTokenAsync(MsalTestConstants.Scope).Result;

                // make sure that all cache entities are stored with "preferred_cache" environment
                // (it is taken from metadata in instance discovery response)
                ValidateCacheEntitiesEnvironment(app.UserTokenCache, MsalTestConstants.ProductionPrefCacheEnvironment);

                // silent request targeting at, should return at from cache for any environment alias
                foreach (var envAlias in MsalTestConstants.ProdEnvAliases)
                {
                    result = app.AcquireTokenSilentAsync(MsalTestConstants.Scope,
                                                         app.GetAccountsAsync().Result.First(),
                                                         string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid),
                                                         false).Result;

                    Assert.IsNotNull(result);
                }

                // mock for openId config request for tenant spesific authority
                httpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/v2.0/.well-known/openid-configuration",
                                        MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid),
                    Method          = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityUtidTenant)
                });

                // silent request targeting rt should find rt in cahce for authority with any environment alias
                foreach (var envAlias in MsalTestConstants.ProdEnvAliases)
                {
                    httpManager.AddMockHandler(new MockHttpMessageHandler()
                    {
                        Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/oauth2/v2.0/token",
                                            MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid),
                        Method   = HttpMethod.Post,
                        PostData = new Dictionary <string, string>()
                        {
                            { "grant_type", "refresh_token" }
                        },
                        // return not retriable status code
                        ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage()
                    });

                    try
                    {
                        result = null;
                        result = app.AcquireTokenSilentAsync(MsalTestConstants.ScopeForAnotherResource,
                                                             app.GetAccountsAsync().Result.First(),
                                                             string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid),
                                                             false).Result;
                    }
                    catch (AggregateException ex)
                    {
                        Assert.IsNotNull(ex.InnerException);
                        Assert.IsTrue(ex.InnerException is MsalUiRequiredException);
                    }

                    Assert.IsNull(result);
                }
            }
        }
        public async Task NoCacheLookupAsync()
        {
            MyReceiver myReceiver = new MyReceiver();

            using (MockHttpAndServiceBundle harness = CreateTestHarness(telemetryCallback: myReceiver.HandleTelemetryEvents))
            {
                TokenCache cache = new TokenCache(harness.ServiceBundle, false);

                MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem(
                    TestConstants.ProductionPrefNetworkEnvironment,
                    TestConstants.ClientId,
                    TestConstants.s_scope.AsSingleString(),
                    TestConstants.Utid,
                    null,
                    new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3599)),
                    new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(7200)),
                    MockHelpers.CreateClientInfo());

                string atKey = atItem.GetKey().ToString();
                atItem.Secret = atKey;
                ((ITokenCacheInternal)cache).Accessor.SaveAccessToken(atItem);

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

                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui);

                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityHomeTenant);

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    cache,
                    extraQueryParameters: new Dictionary <string, string>
                {
                    { "extra", "qp" }
                });
                parameters.RedirectUri = new Uri("some://uri");
                parameters.LoginHint   = TestConstants.DisplayableId;
                AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.SelectAccount,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                };

                InteractiveRequest request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

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

                Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllRefreshTokens().Count());
                Assert.AreEqual(2, ((ITokenCacheInternal)cache).Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(result.AccessToken, "some-access-token");

                Assert.IsNotNull(
                    myReceiver.EventsReceived.Find(
                        anEvent => // Expect finding such an event
                        anEvent[EventBase.EventNameKey].EndsWith("ui_event") &&
                        anEvent[UiEvent.UserCancelledKey] == "false"));
                Assert.IsNotNull(
                    myReceiver.EventsReceived.Find(
                        anEvent => // Expect finding such an event
                        anEvent[EventBase.EventNameKey].EndsWith("api_event") &&
                        anEvent[ApiEvent.PromptKey] == "select_account"));
                Assert.IsNotNull(
                    myReceiver.EventsReceived.Find(
                        anEvent => // Expect finding such an event
                        anEvent[EventBase.EventNameKey].EndsWith("ui_event") &&
                        anEvent[UiEvent.AccessDeniedKey] == "false"));
            }
        }
        public async Task VerifyAuthorizationResultTestAsync()
        {
            using (MockHttpAndServiceBundle harness = CreateTestHarness())
            {
                MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);

                MockWebUI webUi = new MockWebUI()
                {
                    MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?error=" + OAuth2Error.LoginRequired),
                };
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi);

                AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters(
                    TestConstants.AuthorityHomeTenant,
                    TestConstants.s_scope,
                    new TokenCache(harness.ServiceBundle, false),
                    extraQueryParameters: new Dictionary <string, string> {
                    { "extra", "qp" }
                });
                parameters.RedirectUri = new Uri("some://uri");
                parameters.LoginHint   = TestConstants.DisplayableId;
                AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters
                {
                    Prompt = Prompt.ForceLogin,
                    ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(),
                };

                InteractiveRequest request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

                var ex = await AssertException.TaskThrowsAsync <MsalUiRequiredException>(
                    () => request.RunAsync())
                         .ConfigureAwait(false);

                Assert.AreEqual(
                    MsalError.NoPromptFailedError,
                    ex.ErrorCode);

                Assert.AreEqual(
                    UiRequiredExceptionClassification.PromptNeverFailed,
                    ex.Classification);


                webUi = new MockWebUI
                {
                    MockResult = AuthorizationResult.FromUri(
                        TestConstants.AuthorityHomeTenant + "?error=invalid_request&error_description=some error description")
                };
                MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi);

                request = new InteractiveRequest(
                    parameters,
                    interactiveParameters);

                var ex2 = await AssertException.TaskThrowsAsync <MsalServiceException>(
                    () => request.RunAsync())
                          .ConfigureAwait(false);

                Assert.AreEqual("invalid_request", ex2.ErrorCode);
                Assert.AreEqual("some error description", ex2.Message);
            }
        }