public async Task GetAuthorizationRequestUrlB2CTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var app = ConfidentialClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                          .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                          .WithRedirectUri(MsalTestConstants.RedirectUri)
                          .WithClientSecret(MsalTestConstants.ClientSecret)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                // add mock response for tenant endpoint discovery
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateSuccessResponseMessage(
                        File.ReadAllText(
                            ResourceHelper.GetTestResourceRelativePath(@"OpenidConfiguration-QueryParams-B2C.json")))
                });

                var uri = await app
                          .GetAuthorizationRequestUrl(MsalTestConstants.Scope)
                          .WithLoginHint(MsalTestConstants.DisplayableId)
                          .ExecuteAsync(CancellationToken.None)
                          .ConfigureAwait(false);

                Assert.IsNotNull(uri);
                Dictionary <string, string> qp = CoreHelpers.ParseKeyValueList(uri.Query.Substring(1), '&', true, null);
                Assert.IsNotNull(qp);

                Assert.AreEqual("my-policy", qp["p"]);
                ValidateCommonQueryParams(qp);
                Assert.AreEqual("offline_access openid profile r1/scope1 r1/scope2", qp["scope"]);
            }
        }
Ejemplo n.º 2
0
        public async Task AcquireTokenByRefreshTokenTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);

                var app = ConfidentialClientApplicationBuilder
                          .Create(TestConstants.ClientId)
                          .WithAuthority(new Uri(TestConstants.AuthorityCommonTenant), true)
                          .WithRedirectUri(TestConstants.RedirectUri)
                          .WithClientSecret(TestConstants.ClientSecret)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                var result = await(app as IByRefreshToken)
                             .AcquireTokenByRefreshToken(null, "SomeRefreshToken")
                             .ExecuteAsync(CancellationToken.None)
                             .ConfigureAwait(false);

                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
                Assert.IsNotNull(result.AccessToken);
                Assert.AreEqual(result.AccessToken, "some-access-token");

                app.UserTokenCacheInternal.Accessor.Clear();
                httpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant);
                result = await((IByRefreshToken)app)
                         .AcquireTokenByRefreshToken(TestConstants.s_scope, "SomeRefreshToken")
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
                Assert.IsNotNull(result.AccessToken);
                Assert.AreEqual(result.AccessToken, "some-access-token");
            }
        }
        private async Task ValidateGetAccountsWithDiscoveryAsync(string tokenCacheAsString)
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var pcaGlobal = InitPcaFromCacheString(AzureCloudInstance.AzurePublic, httpManager, tokenCacheAsString);
                var pcaDe     = InitPcaFromCacheString(AzureCloudInstance.AzureGermany, httpManager, tokenCacheAsString);
                var pcaCn     = InitPcaFromCacheString(AzureCloudInstance.AzureChina, httpManager, tokenCacheAsString);

                // Act
                var accountsGlobal = await pcaGlobal.GetAccountsAsync().ConfigureAwait(false);

                var accountsDe = await pcaDe.GetAccountsAsync().ConfigureAwait(false);

                var accountsCn = await pcaCn.GetAccountsAsync().ConfigureAwait(false);

                // Assert
                Assert.AreEqual("login.microsoftonline.com", accountsGlobal.Single().Environment);
                Assert.IsTrue(!accountsDe.Any());
                Assert.AreEqual("login.chinacloudapi.cn", accountsCn.Single().Environment);
            }
        }
Ejemplo n.º 4
0
        public async Task RegionFallbackToGlobalAsync()
        {
            _httpManager.AddRegionDiscoveryMockHandlerNotFound();
            _httpManager.AddInstanceDiscoveryMockHandler();
            _httpManager.AddMockHandler(CreateTokenResponseHttpHandler(true));

            var app = CreateApp();

            try
            {
                AuthenticationResult result = await app
                                              .AcquireTokenForClient(TestConstants.s_scope)
                                              .WithPreferredAzureRegion(true, string.Empty, true)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                Assert.IsNotNull(result.AccessToken);
            }
            catch (MsalServiceException)
            {
                Assert.Fail("Fallback to global failed.");
            }
        }
        public async Task FederatedUsernamePasswordWithSecureStringAcquireTokenTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                httpManager.AddInstanceDiscoveryMockHandler();
                AddMockResponseForFederatedAccounts(httpManager);

                var app =
                    new PublicClientApplication(serviceBundle, MsalTestConstants.ClientId,
                                                ClientApplicationBase.DefaultAuthority);

                var result = await app.AcquireTokenByUsernamePasswordAsync(
                    MsalTestConstants.Scope,
                    MsalTestConstants.User.Username,
                    _secureString).ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("some-access-token", result.AccessToken);
                Assert.IsNotNull(result.Account);
                Assert.AreEqual(MsalTestConstants.User.Username, result.Account.Username);
            }
        }
        public async Task ManagedUsernameSecureStringPasswordAcquireTokenTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                httpManager.AddInstanceDiscoveryMockHandler();
                AddMockResponseforManagedAccounts(httpManager);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    Method          = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(),
                    PostDataObject  = new Dictionary <string, object>
                    {
                        { "grant_type", "password" },
                        { "username", MsalTestConstants.User.Username },
                        { "password", _secureString }
                    }
                });

                var app = new PublicClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId,
                    ClientApplicationBase.DefaultAuthority);

                var result = await app.AcquireTokenByUsernamePasswordAsync(
                    MsalTestConstants.Scope,
                    MsalTestConstants.User.Username,
                    _secureString).ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("some-access-token", result.AccessToken);
                Assert.IsNotNull(result.Account);
                Assert.AreEqual(MsalTestConstants.User.Username, result.Account.Username);
            }
        }
        public void AcquireTokenByIntegratedWindowsAuthTest_UnknownUser()
        {
            // Arrange
            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityHomeTenant);

                // user realm discovery - unknown user type
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    Method          = HttpMethod.Get,
                    ResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(
                            "{\"ver\":\"1.0\"," +
                            "\"account_type\":\"Bogus\"}")
                    }
                });

                var app =
                    new PublicClientApplication(serviceBundle, MsalTestConstants.ClientId,
                                                ClientApplicationBase.DefaultAuthority);

                // Act
                var exception = AssertException.TaskThrows <MsalClientException>(
                    async() => await app.AcquireTokenByIntegratedWindowsAuthAsync(
                        MsalTestConstants.Scope,
                        MsalTestConstants.User.Username)
                    .ConfigureAwait(false));

                // Assert
                Assert.AreEqual(MsalError.UnknownUserType, exception.ErrorCode);
            }
        }
Ejemplo n.º 8
0
        public async Task GetAuthorizationRequestUrlDuplicateParamsTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var app = ConfidentialClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                          .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                          .WithRedirectUri(MsalTestConstants.RedirectUri)
                          .WithClientSecret(MsalTestConstants.ClientSecret)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                httpManager.AddMockHandlerForTenantEndpointDiscovery(app.Authority);

                try
                {
                    var uri = await app
                              .GetAuthorizationRequestUrl(MsalTestConstants.Scope)
                              .WithLoginHint(MsalTestConstants.DisplayableId)
                              .WithExtraQueryParameters("[email protected]")
                              .ExecuteAsync(CancellationToken.None)
                              .ConfigureAwait(false);

                    Assert.Fail("MSALException should be thrown here");
                }
                catch (MsalException exc)
                {
                    Assert.AreEqual("duplicate_query_parameter", exc.ErrorCode);
                    Assert.AreEqual("Duplicate query parameter 'login_hint' in extraQueryParameters", exc.Message);
                }
                catch (Exception ex)
                {
                    Assert.Fail("Wrong type of exception thrown: " + ex);
                }
            }
        }
        public async Task AcquireTokenByIntegratedWindowsAuthTest_UnknownUserAsync()
        {
            // Arrange
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                // user realm discovery - unknown user type
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
                    {
                        Content = new StringContent(
                            "{\"ver\":\"1.0\"," +
                            "\"account_type\":\"Bogus\"}")
                    }
                });

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

                // Act
                MsalClientException exception = await AssertException.TaskThrowsAsync <MsalClientException>(
                    async() => await app
                    .AcquireTokenByIntegratedWindowsAuth(TestConstants.s_scope)
                    .WithUsername(TestConstants.s_user.Username)
                    .ExecuteAsync(CancellationToken.None)
                    .ConfigureAwait(false)).ConfigureAwait(false);

                // Assert
                Assert.AreEqual(MsalError.UnknownUserType, exception.ErrorCode);
            }
        }
        public async Task FederatedUsernamePasswordCommonAuthorityTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();
                AddMockHandlerDefaultUserRealmDiscovery(httpManager);
                AddMockHandlerMex(httpManager);
                AddMockHandlerWsTrustUserName(httpManager);

                // AAD
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedUrl     = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateInvalidRequestTokenResponseMessage()
                });

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

                // Call acquire token
                MsalServiceException result = await AssertException.TaskThrowsAsync <MsalServiceException>(
                    async() => await app.AcquireTokenByUsernamePassword(
                        TestConstants.s_scope,
                        TestConstants.s_user.Username,
                        _secureString).ExecuteAsync(CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false);

                // Check inner exception
                Assert.AreEqual(MsalError.InvalidRequest, result.ErrorCode);

                // There should be no cached entries.
                Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
            }
        }
        public async Task ManagedUsernameSecureStringPasswordAcquireTokenTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();
                AddMockResponseforManagedAccounts(httpManager);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod         = HttpMethod.Post,
                    ResponseMessage        = MockHelpers.CreateSuccessTokenResponseMessage(),
                    ExpectedPostDataObject = new Dictionary <string, object>
                    {
                        { "grant_type", "password" },
                        { "username", TestConstants.s_user.Username },
                        { "password", _secureString }
                    }
                });

                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
                                              .WithHttpManager(httpManager)
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .BuildConcrete();

                AuthenticationResult result = await app.AcquireTokenByUsernamePassword(
                    TestConstants.s_scope,
                    TestConstants.s_user.Username,
                    _secureString).ExecuteAsync(CancellationToken.None).ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("some-access-token", result.AccessToken);
                Assert.IsNotNull(result.Account);
                Assert.AreEqual(TestConstants.s_user.Username, result.Account.Username);
            }
        }
Ejemplo n.º 12
0
        public void AcquireTokenSilentScopeAndUserOverloadWithNoMatchingScopesInCacheTest()
        {
            // this test ensures that the API can
            // get authority (if unique) from the cache entries where scope does not match.
            // it should only happen for case where no authority is passed.

            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                PublicClientApplication app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                                              .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                                              .WithHttpManager(httpManager)
                                              .BuildConcrete();

                _tokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor);
                app.UserTokenCacheInternal.Accessor.DeleteAccessToken(
                    new MsalAccessTokenCacheKey(
                        MsalTestConstants.ProductionPrefNetworkEnvironment,
                        MsalTestConstants.Utid,
                        MsalTestConstants.UserIdentifier,
                        MsalTestConstants.ClientId,
                        MsalTestConstants.ScopeForAnotherResourceStr));

                Task <AuthenticationResult> task = app
                                                   .AcquireTokenSilent(
                    MsalTestConstants.ScopeForAnotherResource.ToArray(),
                    new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null))
                                                   .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result = task.Result;
                Assert.IsNotNull(result);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(MsalTestConstants.ScopeForAnotherResource.AsSingleString(), result.Scopes.AsSingleString());
                Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
            }
        }
Ejemplo n.º 13
0
        public async Task AcquireTokenSilent_LoginHintAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                                              .WithAuthority(new Uri(MsalTestConstants.AuthorityTestTenant), true)
                                              .WithHttpManager(httpManager)
                                              .BuildConcrete();
                _tokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor);

                httpManager.AddInstanceDiscoveryMockHandler();

                AuthenticationResult result = await app.AcquireTokenSilent(
                    MsalTestConstants.Scope.ToArray(),
                    MsalTestConstants.DisplayableId)
                                              .WithAuthority(app.Authority, false)
                                              .ExecuteAsync()
                                              .ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(MsalTestConstants.Scope.AsSingleString(), result.Scopes.AsSingleString());
            }
        }
Ejemplo n.º 14
0
        [WorkItem(1403)] // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1403
        public async Task FooAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var app = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                          .WithClientSecret(TestConstants.ClientSecret)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                var handler = httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
                handler.ExpectedPostData = new Dictionary <string, string>()
                {
                    // Bug 1403: Do not add reserved scopes profile, offline_access and openid to Confidential Client request
                    { "scope", TestConstants.s_scope.AsSingleString() }
                };

                var result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray())
                             .WithAuthority(TestConstants.AuthorityUtidTenant)
                             .ExecuteAsync(CancellationToken.None)
                             .ConfigureAwait(false);
            }
        }
        public async Task TokensAreInterchangable_NonRegional_To_Regional_Async()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandler(CreateTokenResponseHttpHandler(false));

                IConfidentialClientApplication appWithRegion = CreateCca(
                    httpManager,
                    ConfidentialClientApplication.AttemptRegionDiscovery);
                InMemoryTokenCache memoryTokenCache = new InMemoryTokenCache();
                memoryTokenCache.Bind(appWithRegion.AppTokenCache);

                IConfidentialClientApplication appWithoutRegion = CreateCca(
                    httpManager,
                    null);
                memoryTokenCache.Bind(appWithoutRegion.AppTokenCache);

                AuthenticationResult result = await appWithoutRegion
                                              .AcquireTokenForClient(TestConstants.s_scope)
                                              .ExecuteAsync(CancellationToken.None)
                                              .ConfigureAwait(false);

                Assert.IsTrue(result.AuthenticationResultMetadata.TokenSource == TokenSource.IdentityProvider);

                httpManager.AddRegionDiscoveryMockHandler("uscentral");

                // when switching to non-region, token is found in the cache
                result = await appWithRegion
                         .AcquireTokenForClient(TestConstants.s_scope)
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

                Assert.IsTrue(result.AuthenticationResultMetadata.TokenSource == TokenSource.Cache);
            }
        }
Ejemplo n.º 16
0
        public async Task RegionFallbackToGlobalAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddRegionDiscoveryMockHandlerNotFound();
                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandler(CreateTokenResponseHttpHandler(false));

                IConfidentialClientApplication app = CreateCca(
                    httpManager,
                    ConfidentialClientApplication.AttemptRegionDiscovery);

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

                    Assert.IsNotNull(result.AccessToken);

                    Assert.AreEqual(null, result.ApiEvent.RegionUsed);
                    Assert.IsNull(result.ApiEvent.AutoDetectedRegion);
                    Assert.AreEqual(RegionAutodetectionSource.FailedAutoDiscovery, result.ApiEvent.RegionAutodetectionSource);
                    Assert.AreEqual(RegionOutcome.FallbackToGlobal, result.ApiEvent.RegionOutcome);
                    Assert.IsNull(result.AuthenticationResultMetadata.RegionDetails.RegionUsed);
                    Assert.AreEqual(RegionOutcome.FallbackToGlobal, result.AuthenticationResultMetadata.RegionDetails.RegionOutcome);
                    Assert.IsTrue(result.AuthenticationResultMetadata.RegionDetails.AutoDetectionError
                                  .Contains(TestConstants.RegionDiscoveryIMDSCallFailedMessage));
                }
                catch (MsalServiceException)
                {
                    Assert.Fail("Fallback to global failed.");
                }
            }
        }
        public async Task AcquireTokenByOboNullCcsTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();
                var extraUnexpectedHeaders = new List <string>()
                {
                    { Constants.CcsRoutingHintHeader }
                };
                AddMockHandlerAadSuccess(httpManager, TestConstants.AuthorityCommonTenant, extraUnexpectedHeaders);

                var cca = ConfidentialClientApplicationBuilder
                          .Create(TestConstants.ClientId)
                          .WithClientSecret(TestConstants.ClientSecret)
                          .WithAuthority(TestConstants.AuthorityCommonTenant)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                UserAssertion userAssertion = new UserAssertion(TestConstants.DefaultAccessToken);
                var           result        = await cca.AcquireTokenOnBehalfOf(TestConstants.s_scope, userAssertion)
                                              .WithCcsRoutingHint("")
                                              .WithCcsRoutingHint("", "")
                                              .ExecuteAsync().ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("some-access-token", result.AccessToken);

                result = await cca.AcquireTokenOnBehalfOf(TestConstants.s_scope, userAssertion)
                         .WithCcsRoutingHint("")
                         .WithCcsRoutingHint("", "")
                         .ExecuteAsync().ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.AreEqual("some-access-token", result.AccessToken);
            }
        }
Ejemplo n.º 18
0
        public void GetAuthorizationRequestUrlCustomRedirectUriTest()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var app = ConfidentialClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                          .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                          .WithRedirectUri(MsalTestConstants.RedirectUri)
                          .WithClientSecret(MsalTestConstants.ClientSecret)
                          .WithHttpManager(httpManager)
                          .BuildConcrete();

                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityGuestTenant);

                const string CustomRedirectUri = "custom://redirect-uri";
                Task <Uri>   task = app
                                    .GetAuthorizationRequestUrl(MsalTestConstants.Scope)
                                    .WithRedirectUri(CustomRedirectUri)
                                    .WithLoginHint(MsalTestConstants.DisplayableId)
                                    .WithExtraQueryParameters("extra=qp")
                                    .WithExtraScopesToConsent(MsalTestConstants.ScopeForAnotherResource)
                                    .WithAuthority(MsalTestConstants.AuthorityGuestTenant)
                                    .ExecuteAsync(CancellationToken.None);

                var uri = task.Result;
                Assert.IsNotNull(uri);
                Assert.IsTrue(
                    uri.AbsoluteUri.StartsWith(MsalTestConstants.AuthorityGuestTenant, StringComparison.CurrentCulture));
                Dictionary <string, string> qp = CoreHelpers.ParseKeyValueList(uri.Query.Substring(1), '&', true, null);
                ValidateCommonQueryParams(qp, CustomRedirectUri);
                Assert.AreEqual("offline_access openid profile r1/scope1 r1/scope2 r2/scope1 r2/scope2", qp["scope"]);
                Assert.IsFalse(qp.ContainsKey("client_secret"));
                Assert.AreEqual("qp", qp["extra"]);
            }
        }
Ejemplo n.º 19
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());
            }
        }
Ejemplo n.º 20
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);
            }
        }
Ejemplo n.º 21
0
        [WorkItem(695)] // Fix for https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/695
        public void AcquireTokenSilentForceRefreshFalseMultipleTenantsTest()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                                              .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                                              .WithHttpManager(httpManager)
                                              .WithTelemetry(new TraceTelemetryConfig())
                                              .BuildConcrete();

                // PopulateCache() creates two access tokens
                var tokenCacheHelper = new TokenCacheHelper();
                tokenCacheHelper.PopulateCache(app.UserTokenCacheInternal.Accessor);

                Task <AuthenticationResult> task = app
                                                   .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null))
                                                   .WithAuthority(TestConstants.AuthorityCommonTenant)
                                                   .WithForceRefresh(false)
                                                   .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result = task.Result;
                Assert.IsNotNull(result);
                Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result.Scopes.AsSingleString());
                Assert.AreEqual(0, httpManager.QueueSize);

                Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());

                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityGuidTenant2);
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        TestConstants.UniqueId,
                        TestConstants.DisplayableId,
                        TestConstants.s_scope.ToArray())
                });

                // Same user, scopes, clientId, but different authority
                // Should result in new AccessToken, but same refresh token
                Task <AuthenticationResult> task2 = app
                                                    .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null))
                                                    .WithAuthority(TestConstants.AuthorityGuidTenant2)
                                                    .WithForceRefresh(false)
                                                    .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result2 = task2.Result;
                Assert.IsNotNull(result2);
                Assert.AreEqual(TestConstants.DisplayableId, result2.Account.Username);
                Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result2.Scopes.AsSingleString());

                Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());

                httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityGuidTenant);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        TestConstants.UniqueId,
                        TestConstants.DisplayableId,
                        TestConstants.s_scope.ToArray())
                });

                // Same user, scopes, clientId, but different authority
                // Should result in new AccessToken, but same refresh token
                Task <AuthenticationResult> task3 = app
                                                    .AcquireTokenSilent(
                    TestConstants.s_scope.ToArray(),
                    new Account(TestConstants.s_userIdentifier, TestConstants.DisplayableId, null))
                                                    .WithAuthority(TestConstants.AuthorityGuidTenant)
                                                    .WithForceRefresh(false)
                                                    .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result3 = task3.Result;
                Assert.IsNotNull(result3);
                Assert.AreEqual(TestConstants.DisplayableId, result3.Account.Username);
                Assert.AreEqual(TestConstants.s_scope.ToArray().AsSingleString(), result3.Scopes.AsSingleString());

                Assert.AreEqual(4, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
            }
        }
Ejemplo n.º 22
0
        public void UnifiedCache_MsalStoresToAndReadRtFromAdalCache()
        {
            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);

                httpManager.AddInstanceDiscoveryMockHandler();

                PublicClientApplication app = new PublicClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId,
                    ClientApplicationBase.DefaultAuthority)
                {
                    UserTokenCache =
                    {
                        LegacyCachePersistence = new TestLegacyCachePersistance()
                    }
                };

                MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success,
                                                                           app.RedirectUri + "?code=some-code"));
                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityHomeTenant);
                httpManager.AddSuccessTokenResponseMockHandlerForPost();

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

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

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

                var requestContext = new RequestContext(null, new MsalLogger(Guid.Empty, null));
                var accounts       =
                    app.UserTokenCache.GetAccounts(MsalTestConstants.AuthorityCommonTenant, false, requestContext);
                foreach (IAccount account in accounts)
                {
                    app.UserTokenCache.RemoveMsalAccount(account, requestContext);
                }

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    Method   = HttpMethod.Post,
                    PostData = 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.AcquireTokenSilentAsync(
                    MsalTestConstants.Scope,
                    result.Account,
                    MsalTestConstants.AuthorityCommonTenant,
                    false).Result;

                Assert.IsNotNull(result1);
            }
        }
 private static void MockInstanceDiscoveryAndOpenIdRequest(MockHttpManager mockHttpManager)
 {
     mockHttpManager.AddInstanceDiscoveryMockHandler();
 }
        public async Task WAM_AccountIds_GetMerged_Async()
        {
            // Arrange
            using (var httpManager = new MockHttpManager())
            {
                var cache = new InMemoryTokenCache();
                httpManager.AddInstanceDiscoveryMockHandler();

                var mockBroker = Substitute.For <IBroker>();
                mockBroker.IsBrokerInstalledAndInvokable(AuthorityType.Aad).Returns(true);

                var msalTokenResponse1 = CreateMsalTokenResponseFromWam("wam1");
                var msalTokenResponse2 = CreateMsalTokenResponseFromWam("wam2");
                var msalTokenResponse3 = CreateMsalTokenResponseFromWam("wam3");

                // 2 apps must share the token cache, like FOCI apps, for this test to be interesting
                var pca1 = PublicClientApplicationBuilder.Create(TestConstants.ClientId)
                           .WithExperimentalFeatures(true)
                           .WithTestBroker(mockBroker)
                           .WithHttpManager(httpManager)
                           .BuildConcrete();

                var pca2 = PublicClientApplicationBuilder.Create(TestConstants.ClientId2)
                           .WithExperimentalFeatures(true)
                           .WithTestBroker(mockBroker)
                           .WithHttpManager(httpManager)
                           .BuildConcrete();

                cache.Bind(pca1.UserTokenCache);
                cache.Bind(pca2.UserTokenCache);

                pca1.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker;
                pca2.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker;

                // Act
                mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse1));
                await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);

                // this should override wam1 id
                mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse2));
                await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);

                mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse3));
                await pca2.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false);

                var accounts1 = await pca1.GetAccountsAsync().ConfigureAwait(false);

                var accounts2 = await pca2.GetAccountsAsync().ConfigureAwait(false);

                // Assert
#if SUPPORTS_BROKER
                var wamAccountIds = (accounts1.Single() as Account).WamAccountIds;
                Assert.AreEqual(2, wamAccountIds.Count);
                Assert.AreEqual("wam2", wamAccountIds[TestConstants.ClientId]);
                Assert.AreEqual("wam3", wamAccountIds[TestConstants.ClientId2]);
                CoreAssert.AssertDictionariesAreEqual(wamAccountIds, (accounts2.Single() as Account).WamAccountIds, StringComparer.Ordinal);
#else
                Assert.IsTrue(accounts1.All(a => (a as IAccountInternal).WamAccountIds == null));
                Assert.IsTrue(accounts2.All(a => (a as IAccountInternal).WamAccountIds == null));
#endif
            }
        }
Ejemplo n.º 25
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);
                }
            }
        }
 internal static void MockInstanceDiscoveryAndOpenIdRequest(MockHttpManager mockHttpManager)
 {
     mockHttpManager.AddInstanceDiscoveryMockHandler();
     mockHttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityHomeTenant);
 }
 private void Init(MockHttpManager httpManager)
 {
     httpManager.AddInstanceDiscoveryMockHandler();
 }
Ejemplo n.º 28
0
        public async Task ConfidentialClientUsingCertificateTestAsync()
        {
            using (var httpManager = new MockHttpManager())
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var cert            = new X509Certificate2(ResourceHelper.GetTestResourceRelativePath("valid.crtfile"));
                var app             = CreateConfidentialClient(httpManager, cert, 3);
                var appCacheAccess  = app.AppTokenCache.RecordAccess();
                var userCacheAccess = app.UserTokenCache.RecordAccess();

                var result = await app.AcquireTokenForClient(TestConstants.s_scope.ToArray()).ExecuteAsync(CancellationToken.None).ConfigureAwait(false);

                Assert.IsNotNull(result);
                Assert.IsNotNull("header.payload.signature", result.AccessToken);
                Assert.AreEqual(TestConstants.s_scope.AsSingleString(), result.Scopes.AsSingleString());
                appCacheAccess.AssertAccessCounts(1, 1);
                userCacheAccess.AssertAccessCounts(0, 0);

                // make sure user token cache is empty
                Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(0, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());

                // check app token cache count to be 1
                Assert.AreEqual(1, app.AppTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(0, app.AppTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); // no RTs are returned

                // assert client credential

                Assert.IsNotNull(app.ClientCredential.CachedAssertion);
                Assert.AreNotEqual(0, app.ClientCredential.ValidTo);

                // save client assertion.
                string cachedAssertion = app.ClientCredential.CachedAssertion;
                long   cacheValidTo    = app.ClientCredential.ValidTo;

                result = await app
                         .AcquireTokenForClient(TestConstants.s_scopeForAnotherResource.ToArray())
                         .ExecuteAsync(CancellationToken.None)
                         .ConfigureAwait(false);

                appCacheAccess.AssertAccessCounts(2, 2);
                userCacheAccess.AssertAccessCounts(0, 0);

                Assert.IsNotNull(result);
                Assert.AreEqual(cacheValidTo, app.ClientCredential.ValidTo);
                Assert.AreEqual(cachedAssertion, app.ClientCredential.CachedAssertion);

                // validate the send x5c forces a refresh of the cached client assertion
                await app
                .AcquireTokenForClient(TestConstants.s_scope.ToArray())
                .WithSendX5C(true)
                .WithForceRefresh(true)
                .ExecuteAsync(CancellationToken.None)
                .ConfigureAwait(false);

                Assert.AreNotEqual(cachedAssertion, app.ClientCredential.CachedAssertion);

                appCacheAccess.AssertAccessCounts(2, 3);
                userCacheAccess.AssertAccessCounts(0, 0);
            }
        }
        [WorkItem(695)] // Fix for https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/695
        public void AcquireTokenSilentForceRefreshMultipleTenantsTest()
        {
            using (var httpManager = new MockHttpManager())
            {
                PublicClientApplication app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId)
                                              .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true)
                                              .WithHttpManager(httpManager)
                                              .BuildConcrete();
                var tokenCacheHelper = new TokenCacheHelper();
                tokenCacheHelper.PopulateCacheWithOneAccessToken(app.UserTokenCacheInternal.Accessor);

                httpManager.AddInstanceDiscoveryMockHandler();
                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        MsalTestConstants.UniqueId,
                        MsalTestConstants.DisplayableId,
                        MsalTestConstants.Scope.ToArray())
                });

                // ForceRefresh=true, so skip cache lookup of Access Token
                // Use refresh token to acquire a new Access Token
                Task <AuthenticationResult> task = app
                                                   .AcquireTokenSilent(
                    MsalTestConstants.Scope.ToArray(),
                    new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null))
                                                   .WithAuthority(MsalTestConstants.AuthorityCommonTenant)
                                                   .WithForceRefresh(true)
                                                   .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result = task.Result;
                Assert.IsNotNull(result);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result.Account.Username);
                Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result.Scopes.AsSingleString());

                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityGuidTenant2);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        MsalTestConstants.UniqueId,
                        MsalTestConstants.DisplayableId,
                        MsalTestConstants.Scope.ToArray())
                });

                Task <AuthenticationResult> task2 = app
                                                    .AcquireTokenSilent(
                    MsalTestConstants.Scope.ToArray(),
                    new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null))
                                                    .WithAuthority(MsalTestConstants.AuthorityGuidTenant2)
                                                    .WithForceRefresh(true)
                                                    .ExecuteAsync(CancellationToken.None);

                // Same user, scopes, clientId, but different authority
                // Should result in new AccessToken, but same refresh token
                AuthenticationResult result2 = task2.Result;
                Assert.IsNotNull(result2);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result2.Account.Username);
                Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result2.Scopes.AsSingleString());

                Assert.AreEqual(2, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());

                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityGuidTenant);

                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        MsalTestConstants.UniqueId,
                        MsalTestConstants.DisplayableId,
                        MsalTestConstants.Scope.ToArray())
                });

                // Same user, scopes, clientId, but different authority
                // Should result in new AccessToken, but same refresh token
                Task <AuthenticationResult> task3 = app
                                                    .AcquireTokenSilent(
                    MsalTestConstants.Scope.ToArray(),
                    new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null))
                                                    .WithAuthority(MsalTestConstants.AuthorityGuidTenant)
                                                    .WithForceRefresh(true)
                                                    .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result3 = task3.Result;
                Assert.IsNotNull(result3);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result3.Account.Username);
                Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result3.Scopes.AsSingleString());

                Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());

                // Use same authority as above, number of access tokens should remain constant
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        MsalTestConstants.UniqueId,
                        MsalTestConstants.DisplayableId,
                        MsalTestConstants.Scope.ToArray())
                });

                Task <AuthenticationResult> task4 = app
                                                    .AcquireTokenSilent(
                    MsalTestConstants.Scope.ToArray(),
                    new Account(MsalTestConstants.UserIdentifier, MsalTestConstants.DisplayableId, null))
                                                    .WithAuthority(MsalTestConstants.AuthorityGuidTenant)
                                                    .WithForceRefresh(true)
                                                    .ExecuteAsync(CancellationToken.None);

                AuthenticationResult result4 = task4.Result;
                Assert.IsNotNull(result4);
                Assert.AreEqual(MsalTestConstants.DisplayableId, result4.Account.Username);
                Assert.AreEqual(MsalTestConstants.Scope.ToArray().AsSingleString(), result4.Scopes.AsSingleString());

                Assert.AreEqual(3, app.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count());
                Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count());
            }
        }
Ejemplo n.º 30
0
        public void UnifiedCache_RemoveAccountIsApplicationSpecific()
        {
            byte[] data = null;

            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);
                // login to app
                var tokenCache = new TokenCache();
                tokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) =>
                {
                    args.TokenCache.Deserialize(data);
                });
                tokenCache.SetAfterAccess((TokenCacheNotificationArgs args) =>
                {
                    data = args.TokenCache.Serialize();
                });

                PublicClientApplication app = new PublicClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId,
                    ClientApplicationBase.DefaultAuthority)
                {
                    UserTokenCache = tokenCache
                };

                httpManager.AddInstanceDiscoveryMockHandler();

                MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success,
                                                                           app.RedirectUri + "?code=some-code"));

                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityHomeTenant);
                httpManager.AddSuccessTokenResponseMockHandlerForPost();

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

                Assert.AreEqual(1, tokenCache.TokenCacheAccessor.GetAllAccountsAsString().Count);
                Assert.AreEqual(1, app.GetAccountsAsync().Result.Count());

                // login tp app1 with same credentials
                var tokenCache1 = new TokenCache();
                tokenCache1.SetBeforeAccess((TokenCacheNotificationArgs args) =>
                {
                    args.TokenCache.Deserialize(data);
                });
                tokenCache1.SetAfterAccess((TokenCacheNotificationArgs args) =>
                {
                    data = args.TokenCache.Serialize();
                });

                PublicClientApplication app1 = new PublicClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId_1,
                    ClientApplicationBase.DefaultAuthority)
                {
                    UserTokenCache = tokenCache1
                };

                MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success,
                                                                           app.RedirectUri + "?code=some-code"));

                httpManager.AddSuccessTokenResponseMockHandlerForPost();

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

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

                Assert.AreEqual(2, tokenCache1.TokenCacheAccessor.GetAllAccessTokensAsString().Count);
                Assert.AreEqual(2, tokenCache1.TokenCacheAccessor.GetAllRefreshTokensAsString().Count);
                Assert.AreEqual(2, tokenCache1.TokenCacheAccessor.GetAllIdTokensAsString().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());
            }
        }