public void FailedValidationTest()
        {
            using (var harness = new MockHttpAndServiceBundle())
            {
                // add mock response for on-premise DRS request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://enterpriseregistration.fabrikam.com/enrollmentserver/contract",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "api-version", "1.0" }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessResponseMessage(
                        ResourceHelper.GetTestResourceRelativePath(File.ReadAllText("drs-response.json")))
                });


                // add mock response for on-premise webfinger request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://fs.fabrikam.com/adfs/.well-known/webfinger",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "resource", "https://fs.contoso.com" },
                        { "rel", "http://schemas.microsoft.com/rel/trusted-realm" }
                    },
                    ResponseMessage = MockHelpers.CreateFailureMessage(HttpStatusCode.NotFound, "not-found")
                });

                Authority instance = Authority.CreateAuthority(harness.ServiceBundle, MsalTestConstants.OnPremiseAuthority);
                Assert.IsNotNull(instance);
                Assert.AreEqual(instance.AuthorityInfo.AuthorityType, AuthorityType.Adfs);

                try
                {
                    var resolver  = new AuthorityEndpointResolutionManager(harness.ServiceBundle);
                    var endpoints = resolver.ResolveEndpointsAsync(
                        instance.AuthorityInfo,
                        MsalTestConstants.FabrikamDisplayableId,
                        RequestContext.CreateForTest(harness.ServiceBundle)).ConfigureAwait(false).GetAwaiter().GetResult();
                    Assert.Fail("ResolveEndpointsAsync should have failed here");
                }
                catch (Exception exc)
                {
                    Assert.IsNotNull(exc);
                }
            }
        }
Example #2
0
        public void FailedValidationTest()
        {
            using (var harness = CreateTestHarness())
            {
                // add mock response for instance validation
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://login.microsoftonline.com/common/discovery/instance",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "api-version", "1.1" },
                        {
                            "authorization_endpoint",
                            "https%3A%2F%2Flogin.microsoft0nline.com%2Fmytenant.com%2Foauth2%2Fv2.0%2Fauthorize"
                        },
                    },
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        HttpStatusCode.BadRequest,
                        "{\"error\":\"invalid_instance\"," + "\"error_description\":\"AADSTS50049: " +
                        "Unknown or invalid instance. Trace " + "ID: b9d0894d-a9a4-4dba-b38e-8fb6a009bc00 " +
                        "Correlation ID: 34f7b4cf-4fa2-4f35-a59b" + "-54b6f91a9c94 Timestamp: 2016-08-23 " +
                        "20:45:49Z\",\"error_codes\":[50049]," + "\"timestamp\":\"2016-08-23 20:45:49Z\"," +
                        "\"trace_id\":\"b9d0894d-a9a4-4dba-b38e-8f" + "b6a009bc00\",\"correlation_id\":\"34f7b4cf-" +
                        "4fa2-4f35-a59b-54b6f91a9c94\"}")
                });

                Authority instance = Authority.CreateAuthority("https://login.microsoft0nline.com/mytenant.com", true);
                Assert.IsNotNull(instance);
                Assert.AreEqual(instance.AuthorityInfo.AuthorityType, AuthorityType.Aad);

                TestCommon.CreateServiceBundleWithCustomHttpManager(harness.HttpManager, authority: instance.AuthorityInfo.CanonicalAuthority, validateAuthority: true);
                try
                {
                    var resolver  = new AuthorityEndpointResolutionManager(harness.ServiceBundle);
                    var endpoints = resolver.ResolveEndpointsAsync(
                        instance.AuthorityInfo,
                        null,
                        new RequestContext(harness.ServiceBundle, Guid.NewGuid()))
                                    .ConfigureAwait(false).GetAwaiter().GetResult();

                    Assert.Fail("validation should have failed here");
                }
                catch (Exception exc)
                {
                    Assert.IsTrue(exc is MsalServiceException);
                    Assert.AreEqual(((MsalServiceException)exc).ErrorCode, "invalid_instance");
                }
            }
        }
Example #3
0
        public async Task UpdateApiversionWhenCurrentVersionExpiresForImdsAsync()
        {
            AddMockedResponse(MockHelpers.CreateNullMessage(System.Net.HttpStatusCode.BadRequest));
            AddMockedResponse(MockHelpers.CreateFailureMessage(System.Net.HttpStatusCode.BadRequest, File.ReadAllText(
                                                                   ResourceHelper.GetTestResourceRelativePath("local-imds-error-response.json"))), expectedParams: false);
            AddMockedResponse(MockHelpers.CreateSuccessResponseMessage(File.ReadAllText(
                                                                           ResourceHelper.GetTestResourceRelativePath("local-imds-response.json"))), apiVersion: "2020-10-01");

            IRegionDiscoveryProvider       regionDiscoveryProvider = new RegionDiscoveryProvider(_httpManager, new NetworkCacheMetadataProvider());
            InstanceDiscoveryMetadataEntry regionalMetadata        = await regionDiscoveryProvider.GetMetadataAsync(new Uri("https://login.microsoftonline.com/common/"), _testRequestContext).ConfigureAwait(false);

            Assert.IsNotNull(regionalMetadata);
            Assert.AreEqual("centralus.login.microsoft.com", regionalMetadata.PreferredNetwork);
        }
        private static void AddTokenResponse(TokenResponseType aadResponse, MockHttpManager httpManager)
        {
            switch (aadResponse)
            {
            case TokenResponseType.Valid:
                var refreshHandler = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage(
                        TestConstants.UniqueId,
                        TestConstants.DisplayableId,
                        TestConstants.s_scope.ToArray())
                };
                httpManager.AddMockHandler(refreshHandler);
                break;

            case TokenResponseType.Invalid_AADUnavailable:
                var refreshHandler1 = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout")
                };
                var refreshHandler2 = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout")
                };

                // MSAL retries once for errors in the 500 - 600 range
                httpManager.AddMockHandler(refreshHandler1);
                httpManager.AddMockHandler(refreshHandler2);
                break;

            case TokenResponseType.Invalid_AADAvailable:
                var handler = new MockHttpMessageHandler()
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage()
                };

                httpManager.AddMockHandler(handler);
                break;

            default:
                throw new NotImplementedException();
            }
        }
        public void FailedValidationTest()
        {
            //add mock response for instance validation
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://login.microsoftonline.com/common/discovery/instance",
                QueryParams = new Dictionary <string, string>
                {
                    { "api-version", "1.0" },
                    { "authorization_endpoint", "https%3A%2F%2Flogin.microsoft0nline.com%2Fmytenant.com%2Foauth2%2Fv2.0%2Fauthorize" },
                },
                ResponseMessage =
                    MockHelpers.CreateFailureMessage(HttpStatusCode.BadRequest, "{\"error\":\"invalid_instance\"," +
                                                     "\"error_description\":\"AADSTS50049: " +
                                                     "Unknown or invalid instance. Trace " +
                                                     "ID: b9d0894d-a9a4-4dba-b38e-8fb6a009bc00 " +
                                                     "Correlation ID: 34f7b4cf-4fa2-4f35-a59b" +
                                                     "-54b6f91a9c94 Timestamp: 2016-08-23 " +
                                                     "20:45:49Z\",\"error_codes\":[50049]," +
                                                     "\"timestamp\":\"2016-08-23 20:45:49Z\"," +
                                                     "\"trace_id\":\"b9d0894d-a9a4-4dba-b38e-8f" +
                                                     "b6a009bc00\",\"correlation_id\":\"34f7b4cf-" +
                                                     "4fa2-4f35-a59b-54b6f91a9c94\"}")
            });

            Authority instance = Authority.CreateAuthority("https://login.microsoft0nline.com/mytenant.com", true);

            Assert.IsNotNull(instance);
            Assert.AreEqual(instance.AuthorityType, AuthorityType.Aad);
            try
            {
                Task.Run(async() =>
                {
                    await instance.ResolveEndpointsAsync(null, new RequestContext(Guid.NewGuid(), null)).ConfigureAwait(false);
                })
                .GetAwaiter()
                .GetResult();
                Assert.Fail("validation should have failed here");
            }
            catch (Exception exc)
            {
                Assert.IsNotNull(exc is MsalServiceException);
                Assert.AreEqual(((MsalServiceException)exc).ErrorCode, "invalid_instance");
            }

            Assert.AreEqual(0, HttpMessageHandlerFactory.MockCount);
        }
Example #6
0
        public void FailedValidationTest()
        {
            //add mock response for on-premise DRS request
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://enterpriseregistration.fabrikam.com/enrollmentserver/contract",
                QueryParams = new Dictionary <string, string>
                {
                    { "api-version", "1.0" }
                },
                ResponseMessage = MockHelpers.CreateSuccessResponseMessage(File.ReadAllText("drs-response.json"))
            });


            //add mock response for on-premise webfinger request
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://fs.fabrikam.com/adfs/.well-known/webfinger",
                QueryParams = new Dictionary <string, string>
                {
                    { "resource", "https://fs.contoso.com" },
                    { "rel", "http://schemas.microsoft.com/rel/trusted-realm" }
                },
                ResponseMessage = MockHelpers.CreateFailureMessage(HttpStatusCode.NotFound, "not-found")
            });

            Authority instance = Authority.CreateAuthority(TestConstants.OnPremiseAuthority, true);

            Assert.IsNotNull(instance);
            Assert.AreEqual(instance.AuthorityType, AuthorityType.Adfs);
            try
            {
                Task.Run(async() =>
                {
                    await instance.ResolveEndpointsAsync(TestConstants.FabrikamDisplayableId, new RequestContext(Guid.NewGuid(), null));
                }).GetAwaiter().GetResult();
                Assert.Fail("ResolveEndpointsAsync should have failed here");
            }
            catch (Exception exc)
            {
                Assert.IsNotNull(exc);
            }

            Assert.AreEqual(0, HttpMessageHandlerFactory.MockCount);
        }
        public async Task UpdateApiversionFailsWithNoNewestVersionsAsync()
        {
            // Arrange
            AddMockedResponse(MockHelpers.CreateNullMessage(System.Net.HttpStatusCode.BadRequest));
            AddMockedResponse(MockHelpers.CreateFailureMessage(System.Net.HttpStatusCode.BadRequest, File.ReadAllText(
                                                                   ResourceHelper.GetTestResourceRelativePath("local-imds-error-response-versions-missing.json"))), expectedParams: false);
            _testRequestContext.ServiceBundle.Config.AzureRegion = ConfidentialClientApplication.AttemptRegionDiscovery;

            // Act
            InstanceDiscoveryMetadataEntry regionalMetadata = await _regionDiscoveryProvider.GetMetadataAsync(new Uri("https://login.microsoftonline.com/common/"), _testRequestContext).ConfigureAwait(false);

            // Assert
            Assert.IsNull(regionalMetadata, "Discovery requested, but it failed.");

            Assert.AreEqual(null, _testRequestContext.ApiEvent.RegionUsed);
            Assert.AreEqual((int)RegionAutodetectionSource.FailedAutoDiscovery, _testRequestContext.ApiEvent.RegionAutodetectionSource);
            Assert.AreEqual((int)RegionOutcome.FallbackToGlobal, _testRequestContext.ApiEvent.RegionOutcome);
        }
        public async Task UpdateImdsApiVersionWhenCurrentVersionExpiresForImdsAsync()
        {
            // Arrange
            AddMockedResponse(MockHelpers.CreateNullMessage(System.Net.HttpStatusCode.BadRequest));
            AddMockedResponse(MockHelpers.CreateFailureMessage(System.Net.HttpStatusCode.BadRequest, File.ReadAllText(
                                                                   ResourceHelper.GetTestResourceRelativePath("local-imds-error-response.json"))), expectedParams: false);
            AddMockedResponse(MockHelpers.CreateSuccessResponseMessage(TestConstants.Region), apiVersion: "2020-10-01");
            _testRequestContext.ServiceBundle.Config.AzureRegion = ConfidentialClientApplication.AttemptRegionDiscovery;

            // Act
            InstanceDiscoveryMetadataEntry regionalMetadata = await _regionDiscoveryProvider.GetMetadataAsync(new Uri("https://login.microsoftonline.com/common/"), _testRequestContext).ConfigureAwait(false);

            // Assert
            ValidateInstanceMetadata(regionalMetadata);
            Assert.AreEqual(TestConstants.Region, _testRequestContext.ApiEvent.RegionUsed);
            Assert.AreEqual((int)RegionAutodetectionSource.Imds, _testRequestContext.ApiEvent.RegionAutodetectionSource);
            Assert.AreEqual((int)RegionOutcome.AutodetectSuccess, _testRequestContext.ApiEvent.RegionOutcome);
        }
Example #9
0
        public async Task UpdateApiversionFailsWithNoNewestVersionsAsync()
        {
            AddMockedResponse(MockHelpers.CreateNullMessage(System.Net.HttpStatusCode.BadRequest));
            AddMockedResponse(MockHelpers.CreateFailureMessage(System.Net.HttpStatusCode.BadRequest, File.ReadAllText(
                                                                   ResourceHelper.GetTestResourceRelativePath("local-imds-error-response-versions-missing.json"))), expectedParams: false);

            try
            {
                IRegionDiscoveryProvider       regionDiscoveryProvider = new RegionDiscoveryProvider(_httpManager, new NetworkCacheMetadataProvider());
                InstanceDiscoveryMetadataEntry regionalMetadata        = await regionDiscoveryProvider.GetMetadataAsync(new Uri("https://login.microsoftonline.com/common/"), _testRequestContext).ConfigureAwait(false);

                Assert.Fail("The call should fail with MsalServiceException as the newest versions were missing in the response.");
            }
            catch (MsalServiceException e)
            {
                Assert.IsNotNull(e);
                Assert.AreEqual(MsalError.RegionDiscoveryFailed, e.ErrorCode);
                Assert.AreEqual(MsalErrorMessage.RegionDiscoveryFailed, e.Message);
            }
        }
        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);
        }
Example #11
0
        private AuthenticationRequestParameters CreateAuthenticationParametersAndSetupMocks(
            MockHttpAndServiceBundle harness,
            int numAuthorizationPendingResults,
            out HashSet <string> expectedScopes,
            bool isAdfs = false)
        {
            var cache      = new TokenCache(harness.ServiceBundle, false);
            var parameters = harness.CreateAuthenticationRequestParameters(
                isAdfs ? TestConstants.OnPremiseAuthority : TestConstants.AuthorityHomeTenant,
                null,
                cache,
                null,
                extraQueryParameters: TestConstants.s_extraQueryParams,
                claims: TestConstants.Claims);

            if (isAdfs)
            {
                harness.HttpManager.AddMockHandler(new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Get,
                    ResponseMessage = MockHelpers.CreateAdfsOpenIdConfigurationResponse(TestConstants.OnPremiseAuthority)
                });
            }
            else
            {
                TestCommon.MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager);
            }

            expectedScopes = new HashSet <string>();
            expectedScopes.UnionWith(TestConstants.s_scope);
            expectedScopes.Add(OAuth2Value.ScopeOfflineAccess);
            expectedScopes.Add(OAuth2Value.ScopeProfile);
            expectedScopes.Add(OAuth2Value.ScopeOpenId);

            IDictionary <string, string> extraQueryParamsAndClaims =
                TestConstants.s_extraQueryParams.ToDictionary(e => e.Key, e => e.Value);

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

            // Mock Handler for device code request
            harness.HttpManager.AddMockHandler(
                new MockHttpMessageHandler
            {
                ExpectedMethod   = HttpMethod.Post,
                ExpectedPostData = new Dictionary <string, string>()
                {
                    { OAuth2Parameter.ClientId, TestConstants.ClientId },
                    { OAuth2Parameter.Scope, expectedScopes.AsSingleString() }
                },
                ResponseMessage     = isAdfs ? CreateAdfsDeviceCodeResponseSuccessMessage() : CreateDeviceCodeResponseSuccessMessage(),
                ExpectedQueryParams = extraQueryParamsAndClaims
            });

            for (int i = 0; i < numAuthorizationPendingResults; i++)
            {
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Post,
                    ExpectedUrl     = isAdfs ? "https://fs.contoso.com/adfs/oauth2/token" : "https://login.microsoftonline.com/home/oauth2/v2.0/token",
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        HttpStatusCode.Forbidden,
                        "{\"error\":\"authorization_pending\"," +
                        "\"error_description\":\"AADSTS70016: Pending end-user authorization." +
                        "\\r\\nTrace ID: f6c2c73f-a21d-474e-a71f-d8b121a58205\\r\\nCorrelation ID: " +
                        "36fe3e82-442f-4418-b9f4-9f4b9295831d\\r\\nTimestamp: 2015-09-24 19:51:51Z\"," +
                        "\"error_codes\":[70016],\"timestamp\":\"2015-09-24 19:51:51Z\",\"trace_id\":" +
                        "\"f6c2c73f-a21d-474e-a71f-d8b121a58205\",\"correlation_id\":" +
                        "\"36fe3e82-442f-4418-b9f4-9f4b9295831d\"}")
                });
            }

            if (numAuthorizationPendingResults > 0)
            {
                // Mock Handler for devicecode->token exchange request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod   = HttpMethod.Post,
                    ExpectedPostData = new Dictionary <string, string>()
                    {
                        { OAuth2Parameter.ClientId, TestConstants.ClientId },
                        { OAuth2Parameter.Scope, expectedScopes.AsSingleString() }
                    },
                    ResponseMessage = isAdfs ? MockHelpers.CreateAdfsSuccessTokenResponseMessage() : MockHelpers.CreateSuccessTokenResponseMessage()
                });
            }

            return(parameters);
        }
Example #12
0
        public void SuccessfulValidationUsingCloudDrsFallbackTest()
        {
            //add mock failure response for on-premise DRS request
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://enterpriseregistration.fabrikam.com/enrollmentserver/contract",
                QueryParams = new Dictionary <string, string>
                {
                    { "api-version", "1.0" }
                },
                ResponseMessage = MockHelpers.CreateFailureMessage(HttpStatusCode.NotFound, "not found")
            });

            //add mock response for cloud DRS request
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://enterpriseregistration.windows.net/fabrikam.com/enrollmentserver/contract",
                QueryParams = new Dictionary <string, string>
                {
                    { "api-version", "1.0" }
                },
                ResponseMessage = MockHelpers.CreateSuccessResponseMessage(File.ReadAllText("drs-response.json"))
            });


            //add mock response for on-premise webfinger request
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method      = HttpMethod.Get,
                Url         = "https://fs.fabrikam.com/adfs/.well-known/webfinger",
                QueryParams = new Dictionary <string, string>
                {
                    { "resource", "https://fs.contoso.com" },
                    { "rel", "http://schemas.microsoft.com/rel/trusted-realm" }
                },
                ResponseMessage = MockHelpers.CreateSuccessWebFingerResponseMessage()
            });

            //add mock response for tenant endpoint discovery
            HttpMessageHandlerFactory.AddMockHandler(new MockHttpMessageHandler
            {
                Method          = HttpMethod.Get,
                Url             = "https://fs.contoso.com/adfs/.well-known/openid-configuration",
                ResponseMessage = MockHelpers.CreateSuccessResponseMessage(File.ReadAllText("OpenidConfiguration-OnPremise.json"))
            });

            Authority instance = Authority.CreateAuthority(TestConstants.OnPremiseAuthority, true);

            Assert.IsNotNull(instance);
            Assert.AreEqual(instance.AuthorityType, AuthorityType.Adfs);
            Task.Run(async() =>
            {
                await instance.ResolveEndpointsAsync(TestConstants.FabrikamDisplayableId, new RequestContext(Guid.NewGuid(), null));
            }).GetAwaiter().GetResult();

            Assert.AreEqual("https://fs.contoso.com/adfs/oauth2/authorize/",
                            instance.AuthorizationEndpoint);
            Assert.AreEqual("https://fs.contoso.com/adfs/oauth2/token/",
                            instance.TokenEndpoint);
            Assert.AreEqual("https://fs.contoso.com/adfs",
                            instance.SelfSignedJwtAudience);
            Assert.AreEqual(0, HttpMessageHandlerFactory.MockCount);
        }
Example #13
0
        public void SuccessfulValidationUsingCloudDrsFallbackTest()
        {
            using (var harness = CreateTestHarness())
            {
                // add mock failure response for on-premise DRS request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://enterpriseregistration.fabrikam.com/enrollmentserver/contract",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "api-version", "1.0" }
                    },
                    ResponseMessage = MockHelpers.CreateFailureMessage(HttpStatusCode.NotFound, "not found")
                });

                // add mock response for cloud DRS request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://enterpriseregistration.windows.net/fabrikam.com/enrollmentserver/contract",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "api-version", "1.0" }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessResponseMessage(
                        ResourceHelper.GetTestResourceRelativePath(File.ReadAllText("drs-response.json")))
                });


                // add mock response for on-premise webfinger request
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod      = HttpMethod.Get,
                    ExpectedUrl         = "https://fs.fabrikam.com/adfs/.well-known/webfinger",
                    ExpectedQueryParams = new Dictionary <string, string>
                    {
                        { "resource", "https://fs.contoso.com" },
                        { "rel", "http://schemas.microsoft.com/rel/trusted-realm" }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessWebFingerResponseMessage()
                });

                // add mock response for tenant endpoint discovery
                harness.HttpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    ExpectedMethod  = HttpMethod.Get,
                    ExpectedUrl     = "https://fs.contoso.com/adfs/.well-known/openid-configuration",
                    ResponseMessage =
                        MockHelpers.CreateSuccessResponseMessage(
                            ResourceHelper.GetTestResourceRelativePath(File.ReadAllText("OpenidConfiguration-OnPremise.json")))
                });

                Authority instance = Authority.CreateAuthority(TestConstants.OnPremiseAuthority);
                Assert.IsNotNull(instance);
                Assert.AreEqual(instance.AuthorityInfo.AuthorityType, AuthorityType.Adfs);

                var resolver  = new AuthorityEndpointResolutionManager(harness.ServiceBundle);
                var endpoints = resolver.ResolveEndpointsAsync(
                    instance.AuthorityInfo,
                    TestConstants.FabrikamDisplayableId,
                    new RequestContext(harness.ServiceBundle, Guid.NewGuid()))
                                .GetAwaiter().GetResult();

                Assert.AreEqual("https://fs.contoso.com/adfs/oauth2/authorize/", endpoints.AuthorizationEndpoint);
                Assert.AreEqual("https://fs.contoso.com/adfs/oauth2/token/", endpoints.TokenEndpoint);
                Assert.AreEqual("https://fs.contoso.com/adfs", endpoints.SelfSignedJwtAudience);
            }
        }
        private async Task <(HttpRequestMessage HttpRequest, Guid Correlationid)> RunAcquireTokenForClientAsync(
            AcquireTokenForClientOutcome outcome, bool forceRefresh = false)
        {
            MockHttpMessageHandler tokenRequestHandler = null;
            Guid correlationId = default;

            switch (outcome)
            {
            case AcquireTokenForClientOutcome.Success:

                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityRegional);
                var authResult = await _app
                                 .AcquireTokenForClient(TestConstants.s_scope)
                                 .WithPreferredAzureRegion(true)
                                 .WithForceRefresh(forceRefresh)
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenForClientOutcome.FallbackToGlobal:
                _harness.HttpManager.AddInstanceDiscoveryMockHandler();
                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityTenant);
                authResult          = await _app
                                      .AcquireTokenForClient(TestConstants.s_scope)
                                      .WithPreferredAzureRegion(true)
                                      .WithForceRefresh(forceRefresh)
                                      .ExecuteAsync()
                                      .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenForClientOutcome.UserProvidedRegion:

                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityRegional);
                authResult          = await _app
                                      .AcquireTokenForClient(TestConstants.s_scope)
                                      .WithPreferredAzureRegion(true, TestConstants.Region)
                                      .WithForceRefresh(forceRefresh)
                                      .ExecuteAsync()
                                      .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenForClientOutcome.UserProvidedInvalidRegion:

                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityRegional);
                authResult          = await _app
                                      .AcquireTokenForClient(TestConstants.s_scope)
                                      .WithPreferredAzureRegion(true, "invalid")
                                      .WithForceRefresh(forceRefresh)
                                      .ExecuteAsync()
                                      .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

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

                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
                                                                                             .AcquireTokenForClient(TestConstants.s_scope)
                                                                                             .WithPreferredAzureRegion(true)
                                                                                             .WithForceRefresh(true)
                                                                                             .WithCorrelationId(correlationId)
                                                                                             .ExecuteAsync())
                                .ConfigureAwait(false);

                break;

            default:
                throw new NotImplementedException();
            }

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

            return(tokenRequestHandler?.ActualRequestMessage, correlationId);
        }
Example #15
0
        private async Task <(HttpRequestMessage HttpRequest, Guid Correlationid)> RunAcquireTokenForClientAsync(
            AcquireTokenForClientOutcome outcome, bool forceRefresh = false, bool serializeCache = false)
        {
            MockHttpMessageHandler tokenRequestHandler = null;
            Guid correlationId = default;

            switch (outcome)
            {
            case AcquireTokenForClientOutcome.Success:

                var app = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                          .WithAuthority(AzureCloudInstance.AzurePublic, TestConstants.TenantId, false)
                          .WithClientSecret(TestConstants.ClientSecret)
                          .WithHttpManager(_harness.HttpManager)
                          .WithAzureRegion()
                          .WithExperimentalFeatures(true)
                          .BuildConcrete();

                if (serializeCache)
                {
                    InMemoryTokenCache mem = new InMemoryTokenCache();
                    mem.Bind(app.AppTokenCache);
                }

                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityRegional);
                var authResult = await app
                                 .AcquireTokenForClient(TestConstants.s_scope)
                                 .WithForceRefresh(forceRefresh)
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenForClientOutcome.FallbackToGlobal:
                _harness.HttpManager.AddInstanceDiscoveryMockHandler();
                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityTenant);

                var app2 = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                           .WithAuthority(AzureCloudInstance.AzurePublic, TestConstants.TenantId, false)
                           .WithClientSecret(TestConstants.ClientSecret)
                           .WithHttpManager(_harness.HttpManager)
                           .WithAzureRegion()
                           .WithExperimentalFeatures(true)
                           .BuildConcrete();

                authResult = await app2
                             .AcquireTokenForClient(TestConstants.s_scope)
                             .WithForceRefresh(forceRefresh)
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

            case AcquireTokenForClientOutcome.UserProvidedRegion:

                tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority: TestConstants.AuthorityRegional);


                var app3 = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                           .WithAuthority(AzureCloudInstance.AzurePublic, TestConstants.TenantId, false)
                           .WithClientSecret(TestConstants.ClientSecret)
                           .WithHttpManager(_harness.HttpManager)
                           .WithAzureRegion(TestConstants.Region)
                           .WithExperimentalFeatures(true)
                           .BuildConcrete();
                authResult = await app3
                             .AcquireTokenForClient(TestConstants.s_scope)
                             .WithForceRefresh(forceRefresh)
                             .ExecuteAsync()
                             .ConfigureAwait(false);

                correlationId = authResult.CorrelationId;
                break;

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

                var app5 = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                           .WithAuthority(AzureCloudInstance.AzurePublic, TestConstants.TenantId, false)
                           .WithClientSecret(TestConstants.ClientSecret)
                           .WithHttpManager(_harness.HttpManager)
                           .WithAzureRegion()
                           .WithExperimentalFeatures(true)
                           .BuildConcrete();

                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>(() =>
                                                                                             app5
                                                                                             .AcquireTokenForClient(TestConstants.s_scope)
                                                                                             .WithForceRefresh(true)
                                                                                             .WithCorrelationId(correlationId)
                                                                                             .ExecuteAsync())
                                .ConfigureAwait(false);

                break;

            default:
                throw new NotImplementedException();
            }

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

            return(tokenRequestHandler?.ActualRequestMessage, correlationId);
        }
        private AuthenticationRequestParameters CreateAuthenticationParametersAndSetupMocks(
            MockHttpManager httpManager,
            int numAuthorizationPendingResults,
            out HashSet <string> expectedScopes)
        {
            var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);

            var authority = Authority.CreateAuthority(serviceBundle, MsalTestConstants.AuthorityHomeTenant, false);

            _cache = new TokenCache()
            {
                ClientId      = MsalTestConstants.ClientId,
                ServiceBundle = serviceBundle
            };

            var parameters = new AuthenticationRequestParameters()
            {
                Authority      = authority,
                ClientId       = MsalTestConstants.ClientId,
                Scope          = MsalTestConstants.Scope,
                TokenCache     = _cache,
                RequestContext = new RequestContext(null, new MsalLogger(Guid.NewGuid(), null))
            };

            TestCommon.MockInstanceDiscoveryAndOpenIdRequest(httpManager);

            expectedScopes = new HashSet <string>();
            expectedScopes.UnionWith(MsalTestConstants.Scope);
            expectedScopes.Add(OAuth2Value.ScopeOfflineAccess);
            expectedScopes.Add(OAuth2Value.ScopeProfile);
            expectedScopes.Add(OAuth2Value.ScopeOpenId);

            // Mock Handler for device code request
            httpManager.AddMockHandler(
                new MockHttpMessageHandler
            {
                Method   = HttpMethod.Post,
                PostData = new Dictionary <string, string>()
                {
                    { OAuth2Parameter.ClientId, MsalTestConstants.ClientId },
                    { OAuth2Parameter.Scope, expectedScopes.AsSingleString() }
                },
                ResponseMessage = CreateDeviceCodeResponseSuccessMessage()
            });

            for (int i = 0; i < numAuthorizationPendingResults; i++)
            {
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    Method          = HttpMethod.Post,
                    Url             = "https://login.microsoftonline.com/home/oauth2/v2.0/token",
                    ResponseMessage = MockHelpers.CreateFailureMessage(
                        HttpStatusCode.Forbidden,
                        "{\"error\":\"authorization_pending\"," +
                        "\"error_description\":\"AADSTS70016: Pending end-user authorization." +
                        "\\r\\nTrace ID: f6c2c73f-a21d-474e-a71f-d8b121a58205\\r\\nCorrelation ID: " +
                        "36fe3e82-442f-4418-b9f4-9f4b9295831d\\r\\nTimestamp: 2015-09-24 19:51:51Z\"," +
                        "\"error_codes\":[70016],\"timestamp\":\"2015-09-24 19:51:51Z\",\"trace_id\":" +
                        "\"f6c2c73f-a21d-474e-a71f-d8b121a58205\",\"correlation_id\":" +
                        "\"36fe3e82-442f-4418-b9f4-9f4b9295831d\"}")
                });
            }

            if (numAuthorizationPendingResults > 0)
            {
                // Mock Handler for devicecode->token exchange request
                httpManager.AddMockHandler(
                    new MockHttpMessageHandler
                {
                    Method   = HttpMethod.Post,
                    PostData = new Dictionary <string, string>()
                    {
                        { OAuth2Parameter.ClientId, MsalTestConstants.ClientId },
                        { OAuth2Parameter.Scope, expectedScopes.AsSingleString() }
                    },
                    ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage()
                });
            }

            return(parameters);
        }