public async Task AuthorityNotInInstanceCache_InstanceDiscoverCallMadeTestAsync()
        {
            const string content = @"{
                            ""tenant_discovery_endpoint"":""https://login.microsoftonline.com/tenant/.well-known/openid-configuration"",
                            ""api-version"":""1.1"",
                            ""metadata"":[{
                                ""preferred_network"":""login.microsoftonline.com"",
                                ""preferred_cache"":""login.windows.net"",
                                ""aliases"":[
                                    ""login.microsoftonline.com"",
                                    ""login.windows.net"",
                                    ""login.microsoft.com"",
                                    ""sts.windows.net""]}]}";

            // creating AuthenticationContext with common Authority
            var authenticationContext =
                new AuthenticationContext(TestConstants.DefaultAuthorityCommonTenant, false, new TokenCache());

            // mock value for authentication returnedUriInput, with cloud_instance_name claim
            var authReturnedUriInputMock = TestConstants.DefaultRedirectUri + "?code=some-code" + "&" +
                                           TokenResponseClaim.CloudInstanceHost + "=" + SovereignAuthorityHost;

            MockHelpers.ConfigureMockWebUI(
                new AuthorizationResult(AuthorizationStatus.Success, authReturnedUriInputMock),
                // validate that authorizationUri passed to WebUi contains instance_aware query parameter
                new Dictionary <string, string> {
                { "instance_aware", "true" }
            });

            HttpMessageHandlerFactory.AddMockHandler(MockHelpers.CreateInstanceDiscoveryMockHandler(TestConstants.GetDiscoveryEndpoint(TestConstants.DefaultAuthorityCommonTenant), content));

            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler(TestConstants.GetDiscoveryEndpoint(TestConstants.DefaultAuthorityBlackforestTenant))
            {
                Method          = HttpMethod.Get,
                ResponseMessage = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StringContent(content)
                }
            });

            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler(TestConstants.GetTokenEndpoint(TestConstants.DefaultAuthorityBlackforestTenant))
            {
                Method          = HttpMethod.Post,
                ResponseMessage =
                    MockHelpers.CreateSuccessTokenResponseMessage(TestConstants.DefaultUniqueId,
                                                                  TestConstants.DefaultDisplayableId, TestConstants.DefaultResource)
            });

            // Assure instance cache is empty
            Assert.AreEqual(0, InstanceDiscovery.InstanceCache.Count());

            await authenticationContext.AcquireTokenAsync(TestConstants.DefaultResource,
                                                          TestConstants.DefaultClientId,
                                                          TestConstants.DefaultRedirectUri, _platformParameters, UserIdentifier.AnyUser, "instance_aware=true");

            // make sure AT was stored in the cache with tenant specific Sovereign Authority in the key
            Assert.AreEqual(1, authenticationContext.TokenCache.tokenCacheDictionary.Count);
            Assert.AreEqual(_sovereignTenantSpecificAuthority,
                            authenticationContext.TokenCache.tokenCacheDictionary.Keys.FirstOrDefault()?.Authority);

            // DE cloud authority now included in instance cache
            Assert.AreEqual(5, InstanceDiscovery.InstanceCache.Count());
            Assert.AreEqual(true, InstanceDiscovery.InstanceCache.Keys.Contains("login.microsoftonline.de"));
            Assert.AreEqual(true, InstanceDiscovery.InstanceCache.Keys.Contains("login.windows.net"));
            Assert.AreEqual(false, InstanceDiscovery.InstanceCache.Keys.Contains("login.partner.microsoftonline.cn"));

            // all mocks are consumed
            Assert.AreEqual(0, HttpMessageHandlerFactory.MockHandlersCount());
        }
Example #2
0
 private void Init(MockHttpManager httpManager)
 {
     httpManager.AddMockHandler(
         MockHelpers.CreateInstanceDiscoveryMockHandler(
             MsalTestConstants.GetDiscoveryEndpoint(MsalTestConstants.AuthorityCommonTenant)));
 }
Example #3
0
 public void ResetInstanceDiscovery()
 {
     InstanceDiscovery.InstanceCache.Clear();
     HttpMessageHandlerFactory.AddMockHandler(MockHelpers.CreateInstanceDiscoveryMockHandler(TestConstants.GetDiscoveryEndpoint(TestConstants.DefaultAuthorityCommonTenant)));
 }
Example #4
0
        private static async Task RunPpeTestAsync(bool validateAuthority, bool authorityIsValid)
        {
            using (var harness = new MockHttpAndServiceBundle())
            {
                MockHttpMessageHandler discoveryHandler = null;
                if (authorityIsValid)
                {
                    discoveryHandler = MockHelpers.CreateInstanceDiscoveryMockHandler(
                        "https://login.microsoftonline.com/common/discovery/instance",
                        TestConstants.DiscoveryJsonResponse);
                }
                else
                {
                    discoveryHandler = new MockHttpMessageHandler()
                    {
                        ExpectedUrl     = "https://login.microsoftonline.com/common/discovery/instance",
                        ExpectedMethod  = HttpMethod.Get,
                        ResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
                        {
                            Content = new StringContent(TestConstants.DiscoveryFailedResponse)
                        }
                    };
                }
                var tokenHttpCallHandler = new MockHttpMessageHandler()
                {
                    ExpectedUrl     = "https://eastus.login.windows-ppe.net/17b189bc-2b81-4ec5-aa51-3e628cbc931b/oauth2/v2.0/token",
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = CreateResponse(true)
                };


                if (authorityIsValid || !validateAuthority) // no calls because authority validation will fail
                {
                    harness.HttpManager.AddMockHandler(discoveryHandler);
                    harness.HttpManager.AddMockHandler(tokenHttpCallHandler);
                }
                else
                {
                    harness.HttpManager.AddMockHandler(discoveryHandler);
                }

                var app = ConfidentialClientApplicationBuilder
                          .Create(TestConstants.ClientId)
                          .WithAuthority("https://login.windows-ppe.net/common", validateAuthority)
                          .WithHttpManager(harness.HttpManager)
                          .WithAzureRegion("eastus")
                          .WithClientSecret(TestConstants.ClientSecret)
                          .Build();

                if (!authorityIsValid && validateAuthority)
                {
                    var ex = await AssertException.TaskThrowsAsync <MsalServiceException>(() => app
                                                                                          .AcquireTokenForClient(TestConstants.s_scope)
                                                                                          .WithAuthority("https://login.windows-ppe.net/17b189bc-2b81-4ec5-aa51-3e628cbc931b")
                                                                                          .ExecuteAsync()).ConfigureAwait(false);

                    Assert.AreEqual(MsalError.InvalidInstance, ex.ErrorCode);
                    var qp = CoreHelpers.ParseKeyValueList(discoveryHandler.ActualRequestMessage.RequestUri.Query.Substring(1), '&', true, null);
                    Assert.AreEqual("https://login.windows-ppe.net/17b189bc-2b81-4ec5-aa51-3e628cbc931b/oauth2/v2.0/authorize", qp["authorization_endpoint"]);
                }
                else
                {
                    AuthenticationResult result = await app
                                                  .AcquireTokenForClient(TestConstants.s_scope)
                                                  .WithAuthority("https://login.windows-ppe.net/17b189bc-2b81-4ec5-aa51-3e628cbc931b")
                                                  .ExecuteAsync()
                                                  .ConfigureAwait(false);

                    Assert.AreEqual("eastus", result.ApiEvent.RegionUsed);
                    Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);
                    Assert.AreEqual(
                        "https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https%3A%2F%2Flogin.windows-ppe.net%2F17b189bc-2b81-4ec5-aa51-3e628cbc931b%2Foauth2%2Fv2.0%2Fauthorize",
                        discoveryHandler.ActualRequestMessage.RequestUri.AbsoluteUri,
                        "Authority validation is made on https://login.microsoftonline.com/ and it validates the auth_endpoint of the non-regional authority");

                    result = await app
                             .AcquireTokenForClient(TestConstants.s_scope)
                             .WithAuthority("https://login.windows-ppe.net/17b189bc-2b81-4ec5-aa51-3e628cbc931b")
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                    Assert.AreEqual("eastus", result.ApiEvent.RegionUsed);
                    Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource);
                }
            }
        }