public async Task AuthorizedRoute_WithCertificateAuthentication_ShouldFailWithUnauthorized_WhenClientCertificateSubjectNameDoesntMatch()
        {
            // Arrange
            string subjectKey = "subject", subjectValue = $"subject-{Guid.NewGuid()}";

            _testServer.AddService <ISecretProvider>(new InMemorySecretProvider((subjectKey, subjectValue)));
            _testServer.AddService(
                new CertificateAuthenticationValidator(
                    new CertificateAuthenticationConfigBuilder()
                    .WithSubject(X509ValidationLocation.SecretProvider, subjectKey)
                    .Build()));

            _testServer.AddFilter(new CertificateAuthenticationFilter());

            using (X509Certificate2 clientCertificate = SelfSignedCertificate.CreateWithSubject("unrecognized-subject-name"))
            {
                _testServer.SetClientCertificate(clientCertificate);
                using (HttpClient client = _testServer.CreateClient())
                {
                    var request = new HttpRequestMessage(
                        HttpMethod.Get,
                        NoneAuthenticationController.Route);

                    // Act
                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        // Arrange
                        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                    }
                }
            }
        }
        public async Task OAuthAuthorizeOperationFilter_ShouldIncludeSecurityDefinitionResponses_OnAuthorizedOperations()
        {
            // Arrange
            using (var client = _testServer.CreateClient())
                // Act
                using (HttpResponseMessage response = await client.GetAsync("swagger/v1/swagger.json"))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    var reader = new OpenApiStreamReader();
                    using (var responseStream = await response.Content.ReadAsStreamAsync())
                    {
                        OpenApiDocument swagger = reader.Read(responseStream, out OpenApiDiagnostic diagnostic);
                        _outputWriter.WriteLine(diagnostic.Errors.Count == 0 ? String.Empty : String.Join(", ", diagnostic.Errors.Select(e => e.Message + ": " + e.Pointer)));

                        Assert.True(
                            swagger.Paths.TryGetValue("/oauth/authorize", out OpenApiPathItem oauthPath),
                            "Cannot find OAuth authorized path in Open API spec file");

                        Assert.True(
                            oauthPath.Operations.TryGetValue(OperationType.Get, out OpenApiOperation oauthOperation),
                            "Cannot find OAuth GET operation in Open API spec file");

                        OpenApiResponses oauthResponses = oauthOperation.Responses;
                        Assert.Contains(oauthResponses, r => r.Key == "401");
                        Assert.Contains(oauthResponses, r => r.Key == "403");
                    }
                }
        }
Esempio n. 3
0
        public async Task AuthorizedRoute_WithCertificateAuthenticationOnAppServiceHeader_ShouldSucceeds_WhenClientCertificateSubjectNameMatches(string actualSubject)
        {
            // Arrange
            _testServer.AddService <ISecretProvider>(new InMemorySecretProvider((SubjectKey, $"CN={actualSubject}")));
            _testServer.AddService(
                new CertificateAuthenticationValidator(
                    new CertificateAuthenticationConfigBuilder()
                    .WithSubject(X509ValidationLocation.SecretProvider, SubjectKey)
                    .Build()));

            const string expectedSubject = "known-subject";

            using (HttpClient client = _testServer.CreateClient())
                using (var cert = SelfSignedCertificate.CreateWithSubject(expectedSubject))
                {
                    var    request           = new HttpRequestMessage(HttpMethod.Get, AuthorizedRoute);
                    string clientCertificate = Convert.ToBase64String(cert.RawData);
                    request.Headers.Add("X-ARR-ClientCert", clientCertificate);

                    // Act
                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        // Arrange
                        bool equalSubject   = expectedSubject == actualSubject;
                        bool isUnauthorized = response.StatusCode == HttpStatusCode.Unauthorized;
                        Assert.True(equalSubject != isUnauthorized, "Client certificate with the same subject name should result in an OK HTTP status code");
                    }
                }
        }
        public async Task GetHealthWithCorrectBearerToken_WithAzureManagedIdentityAuthorization_ReturnsOk()
        {
            // Arrange
            string issuer     = GenerateRandomUri();
            string authority  = GenerateRandomUri();
            string privateKey = GenerateRandomPrivateKey();

            using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
            {
                TokenValidationParameters tokenValidationParameters = testOpenIdServer.GenerateTokenValidationParametersWithValidAudience(issuer, authority, privateKey);
                var reader = new JwtTokenReader(tokenValidationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                _testServer.AddFilter(filters => filters.AddJwtTokenAuthorization(options => options.JwtTokenReader = reader));

                using (HttpClient client = _testServer.CreateClient())
                    using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                    {
                        string accessToken = testOpenIdServer.RequestSecretToken(issuer, authority, privateKey, daysValid: 7);
                        request.Headers.Add(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                        // Act
                        using (HttpResponseMessage response = await client.SendAsync(request))
                        {
                            // Assert
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        }
                    }
            }
        }
        public async Task SendRequest_WithSerilogCorrelationEnrichment_ReturnsOkWithEnrichedCorrelationLogProperties()
        {
            // Arrange
            using (HttpClient client = _testServer.CreateClient())
                // Act
                using (HttpResponseMessage response = await client.GetAsync(Route))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    CorrelationInfo correlationInfo = await AssertAppCorrelationInfoAsync(response);

                    AssertLoggedCorrelationProperties(correlationInfo);
                }
        }
Esempio n. 6
0
        public async Task GetHealthWithCorrectBearerToken_WithIncorrectAzureManagedIdentityAuthorization_ReturnsUnauthorized()
        {
            // Arrange
            using (var testServer = new TestApiServer())
                using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
                {
                    var validationParameters = new TokenValidationParameters
                    {
                        ValidateAudience         = false,
                        ValidateIssuer           = false,
                        ValidateIssuerSigningKey = true,
                        ValidateLifetime         = true
                    };
                    var reader = new JwtTokenReader(validationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                    testServer.AddFilter(filters => filters.AddJwtTokenAuthorization(options => options.JwtTokenReader = reader));

                    using (HttpClient client = testServer.CreateClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                        {
                            string accessToken = await testOpenIdServer.RequestAccessTokenAsync();

                            request.Headers.Add(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                            // Act
                            using (HttpResponseMessage response = await client.SendAsync(request))
                            {
                                // Assert
                                Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                            }
                        }
                }
        }
Esempio n. 7
0
        public async Task GetHealthWithIncorrectBearerToken_WithAzureManagedIdentityAuthorization_ReturnsUnauthorized()
        {
            // Arrange
            using (var testServer = new TestApiServer())
                using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
                {
                    TokenValidationParameters validationParameters = await testOpenIdServer.GenerateTokenValidationParametersAsync();

                    var reader = new JwtTokenReader(validationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                    testServer.AddFilter(filters => filters.AddJwtTokenAuthorization(options => options.JwtTokenReader = reader));

                    using (HttpClient client = testServer.CreateClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                        {
                            string accessToken = $"Bearer {_bogusGenerator.Random.AlphaNumeric(10)}.{_bogusGenerator.Random.AlphaNumeric(50)}.{_bogusGenerator.Random.AlphaNumeric(40)}";
                            request.Headers.Add(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                            // Act
                            using (HttpResponseMessage response = await client.SendAsync(request))
                            {
                                // Assert
                                Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                            }
                        }
                }
        }
Esempio n. 8
0
        public async Task GetHealthWithCorrectBearerToken_WithAzureManagedIdentityAuthorization_ReturnsOk()
        {
            // Arrange
            using (var testServer = new TestApiServer())
                using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
                {
                    TokenValidationParameters validationParameters = await testOpenIdServer.GenerateTokenValidationParametersAsync();

                    var reader = new JwtTokenReader(validationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                    testServer.AddFilter(new AzureManagedIdentityAuthorizationFilter(reader));

                    using (HttpClient client = testServer.CreateClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                        {
                            string accessToken = await testOpenIdServer.RequestAccessTokenAsync();

                            request.Headers.Add(AzureManagedIdentityAuthorizationFilter.DefaultHeaderName, accessToken);

                            // Act
                            using (HttpResponseMessage response = await client.SendAsync(request))
                            {
                                // Assert
                                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            }
                        }
                }
        }
Esempio n. 9
0
        public async Task GetHealthWithCorrectBearerToken_WithAzureManagedIdentityAuthorizationAndCustomClaims_ReturnsOk()
        {
            // Arrange
            string issuer    = $"http://{Util.GetRandomString(10).ToLower()}.com";
            string authority = $"http://{Util.GetRandomString(10).ToLower()}.com";

            RSA    rsa        = new RSACryptoServiceProvider(512);
            string privateKey = rsa.ToCustomXmlString(true);

            using (var testServer = new TestApiServer())
                using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
                {
                    TokenValidationParameters tokenValidationParameters = testOpenIdServer.GenerateTokenValidationParametersWithValidAudience(issuer, authority, privateKey);
                    var reader = new JwtTokenReader(tokenValidationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                    Dictionary <string, string> claimCheck = new Dictionary <string, string> {
                        { JwtClaimTypes.Audience, Guid.NewGuid().ToString() }
                    };
                    testServer.AddFilter(filters => filters.AddJwtTokenAuthorization(options => options.JwtTokenReader = reader, claimCheck));

                    using (HttpClient client = testServer.CreateClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                        {
                            string accessToken = testOpenIdServer.RequestSecretToken(issuer, authority, privateKey, 7, claimCheck);
                            request.Headers.Add(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                            // Act
                            using (HttpResponseMessage response = await client.SendAsync(request))
                            {
                                // Assert
                                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            }
                        }
                }
        }
        public async Task SendRequest_WithVersionTracking_AddsApplicationVersionToResponse()
        {
            // Arrange
            string expected = $"version-{Guid.NewGuid()}";

            _testServer.AddServicesConfig(services => services.AddSingleton <IAppVersion>(provider => new StubAppVersion(expected)));
            _testServer.AddConfigure(app => app.UseVersionTracking());

            using (HttpClient client = _testServer.CreateClient())
                // Act
                using (HttpResponseMessage response = await client.GetAsync(EchoController.Route))
                {
                    // Assert
                    Assert.True(response.Headers.TryGetValues(DefaultHeaderName, out IEnumerable <string> values));
                    Assert.Equal(expected, Assert.Single(values));
                }
        }
Esempio n. 11
0
        public async Task SendRequest_WithCorrelateOptionsNotAllowTransactionInRequest_ResponseWithBadRequest()
        {
            // Arrange
            _testServer.AddServicesConfig(services => services.Configure <CorrelationInfoOptions>(options => options.Transaction.AllowInRequest = false));

            using (HttpClient client = _testServer.CreateClient())
                using (var request = new HttpRequestMessage(HttpMethod.Get, DefaultRoute))
                {
                    request.Headers.Add(DefaultTransactionId, Guid.NewGuid().ToString());

                    // Act
                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        // Assert
                        Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
                        Assert.DoesNotContain(response.Headers, header => header.Key == DefaultOperationId);
                        Assert.DoesNotContain(response.Headers, header => header.Key == DefaultTransactionId);
                    }
                }
        }
        public async Task HandlesBadRequestException_ResultsInExceptionStatusCode()
        {
            // Arrange
            using (HttpClient client = _testServer.CreateClient())
            {
                // Act
                HttpResponseMessage response = await client.GetAsync(RequestBodyTooLargeRoute);

                // Assert
                Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
            }
        }
Esempio n. 13
0
        private async Task <HttpResponseMessage> SendAuthorizedHttpRequestWithHeader(string headerName, IEnumerable <string> headerValues)
        {
            using (HttpClient client = _testServer.CreateClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, AuthorizedRoute)
                {
                    Headers = { { headerName, headerValues } }
                };

                return(await client.SendAsync(request));
            }
        }
        public async Task GetRequest_TracksRequest_ReturnsSuccess()
        {
            // Arrange
            const string headerName = "x-custom-header", headerValue = "custom header value", body = "echo me";

            _testServer.AddConfigure(app => app.UseRequestTracking());
            using (HttpClient client = _testServer.CreateClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, EchoController.Route)
                {
                    Headers = { { headerName, headerValue } },
                    Content = new StringContent($"\"{body}\"", Encoding.UTF8, "application/json")
                };

                // Act
                using (HttpResponseMessage response = await client.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    string content = await response.Content.ReadAsStringAsync();

                    Assert.Equal("echo me", content);

                    IReadOnlyDictionary <ScalarValue, LogEventPropertyValue> eventContext = GetLoggedEventContext();
                    Assert.True(ContainsRequestHeader(eventContext, headerName, headerValue), "Logged event context should contain request header");
                    Assert.False(ContainsRequestBody(eventContext, body), "Shouldn't contain request body");
                }
            }
        }
Esempio n. 15
0
        public async Task GetRequestWithInvalidEndpointFeature_TracksRequest_ReturnsSuccess()
        {
            // Arrange
            string headerName = $"x-custom-header-{Guid.NewGuid()}", headerValue = $"header-{Guid.NewGuid()}";

            _testServer.AddConfigure(app =>
            {
                app.Use((ctx, next) =>
                {
                    ctx.Features.Set(Mock.Of <IEndpointFeature>());
                    return(next());
                });
                app.UseRequestTracking();
            });

            // Act
            using (HttpClient client = _testServer.CreateClient())
                using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                {
                    request.Headers.Add(headerName, headerValue);

                    using (HttpResponseMessage response = await client.SendAsync(request))
                    {
                        // Assert
                        IDictionary <string, string> eventContext = GetLoggedEventContext();
                        Assert.Equal(headerValue, Assert.Contains(headerName, eventContext));
                    }
                }
        }
Esempio n. 16
0
        private async Task <HttpResponseMessage> SendAuthorizedHttpRequest(string route, string headerName = null, IEnumerable <string> headerValues = null, string parameterName = null, string parameterValue = null)
        {
            string requestUri = parameterName == null ? route : route + $"?{parameterName}={parameterValue}";

            using (HttpClient client = _testServer.CreateClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, requestUri);

                if (headerName != null)
                {
                    request.Headers.Add(headerName, headerValues);
                }

                return(await client.SendAsync(request));
            }
        }
Esempio n. 17
0
        public async Task GetHealthWithCorrectBearerToken_WithIncorrectAzureManagedIdentityAuthorization_ReturnsUnauthorized()
        {
            // Arrange
            string issuer    = $"http://{Util.GetRandomString(10).ToLower()}.com";
            string authority = $"http://{Util.GetRandomString(10).ToLower()}.com";

            RSA    rsa        = new RSACryptoServiceProvider(512);
            string privateKey = rsa.ToCustomXmlString(true);

            using (var testServer = new TestApiServer())
                using (var testOpenIdServer = await TestOpenIdServer.StartNewAsync(_outputWriter))
                {
                    var validationParameters = new TokenValidationParameters
                    {
                        ValidateAudience         = false,
                        ValidateIssuer           = false,
                        ValidateIssuerSigningKey = true,
                        ValidateLifetime         = true
                    };

                    var reader = new JwtTokenReader(validationParameters, testOpenIdServer.OpenIdAddressConfiguration);
                    testServer.AddFilter(filters => filters.AddJwtTokenAuthorization(options => options.JwtTokenReader = reader));

                    using (HttpClient client = testServer.CreateClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Get, HealthController.Route))
                        {
                            string accessToken = testOpenIdServer.RequestSecretToken(issuer, authority, privateKey, 7);
                            request.Headers.Add(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                            // Act
                            using (HttpResponseMessage response = await client.SendAsync(request))
                            {
                                // Assert
                                Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                            }
                        }
                }
        }