public void ApplyResult_ManyAllowExposedHeaders_ExposedHeadersHeaderAdded() { // Arrange var result = new CorsResult(); result.AllowedExposedHeaders.Add("foo"); result.AllowedExposedHeaders.Add("bar"); result.AllowedExposedHeaders.Add("baz"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Contains("Access-Control-Expose-Headers", httpContext.Response.Headers.Keys); var value = Assert.Single(httpContext.Response.Headers.Values); Assert.Equal(new[] { "foo,bar,baz" }, value); string[] exposedHeaderValues = httpContext.Response.Headers.GetCommaSeparatedValues("Access-Control-Expose-Headers"); Assert.Equal(3, exposedHeaderValues.Length); Assert.Contains("foo", exposedHeaderValues); Assert.Contains("bar", exposedHeaderValues); Assert.Contains("baz", exposedHeaderValues); }
private async Task InvokeCore(HttpContext context) { var corsPolicy = _policy ?? await _corsPolicyProvider?.GetPolicyAsync(context, _corsPolicyName); if (corsPolicy == null) { Logger?.NoCorsPolicyFound(); await _next(context); return; } var corsResult = CorsService.EvaluatePolicy(context, corsPolicy); if (corsResult.IsPreflightRequest) { CorsService.ApplyResult(corsResult, context.Response); // Since there is a policy which was identified, // always respond to preflight requests. context.Response.StatusCode = StatusCodes.Status204NoContent; return; } else { context.Response.OnStarting(OnResponseStartingDelegate, Tuple.Create(this, context, corsResult)); await _next(context); } }
public void EvaluatePolicy_PreflightRequest_HeadersRequested_NotAllHeaderMatches_ReturnsInvalidResult() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext( method: "OPTIONS", origin: "http://example.com", accessControlRequestMethod: "PUT", accessControlRequestHeaders: new[] { "match", "noMatch" }); var policy = new CorsPolicy(); policy.Origins.Add(CorsConstants.AnyOrigin); policy.Methods.Add("*"); policy.Headers.Add("match"); policy.Headers.Add("foo"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.Empty(result.AllowedHeaders); Assert.Empty(result.AllowedMethods); Assert.Empty(result.AllowedExposedHeaders); Assert.Null(result.AllowedOrigin); }
public void ApplyResult_SimpleRequests_IgnoresFiltering() { // Arrange var result = new CorsResult(); result.AllowedHeaders.Add("Content-Type"); result.AllowedHeaders.Add("Date"); result.AllowedMethods.Add("GET"); result.AllowedMethods.Add("PUT"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert string[] arMethods = httpContext.Response.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlAllowMethods); Assert.Contains("GET", arMethods); Assert.Contains("PUT", arMethods); string[] arHeaders = httpContext.Response.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlAllowHeaders); Assert.Contains("Content-Type", arHeaders); Assert.Contains("Date", arHeaders); }
public void ApplyResult_SomeSimpleAllowMethods_AllowMethodsHeaderAddedForNonSimpleMethods() { // Arrange var result = new CorsResult(); result.AllowedMethods.Add("PUT"); result.AllowedMethods.Add("get"); result.AllowedMethods.Add("DELETE"); result.AllowedMethods.Add("POST"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Contains("Access-Control-Allow-Methods", httpContext.Response.Headers.Keys); var value = Assert.Single(httpContext.Response.Headers.Values); Assert.Equal(new[] { "PUT,DELETE" }, value); string[] methods = httpContext.Response.Headers.GetCommaSeparatedValues("Access-Control-Allow-Methods"); Assert.Equal(2, methods.Length); Assert.Contains("PUT", methods); Assert.Contains("DELETE", methods); }
private Task EvaluateAndApplyPolicy(HttpContext context, CorsPolicy corsPolicy) { if (corsPolicy == null) { Logger.NoCorsPolicyFound(); return(_next(context)); } var corsResult = CorsService.EvaluatePolicy(context, corsPolicy); if (corsResult.IsPreflightRequest) { CorsService.ApplyResult(corsResult, context.Response); // Since there is a policy which was identified, // always respond to preflight requests. context.Response.StatusCode = StatusCodes.Status204NoContent; return(Task.CompletedTask); } else { context.Response.OnStarting(OnResponseStartingDelegate, Tuple.Create(this, context, corsResult)); return(_next(context)); } }
public void EvaluatePolicy_NoOrigin_ReturnsInvalidResult() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext("GET", origin: null); // Act var result = corsService.EvaluatePolicy(requestContext, new CorsPolicy()); // Assert Assert.Null(result.AllowedOrigin); Assert.False(result.VaryByOrigin); }
public void ApplyResult_ReturnsNoHeaders_ByDefault() { // Arrange var result = new CorsResult(); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Empty(httpContext.Response.Headers); }
public void EvaluatePolicy_EmptyOriginsPolicy_ReturnsInvalidResult() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(origin: "http://example.com"); var policy = new CorsPolicy(); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.Null(result.AllowedOrigin); Assert.False(result.VaryByOrigin); }
public void EvaluatePolicy_NoExposedHeaders_NoAllowExposedHeaders() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(origin: "http://example.com"); var policy = new CorsPolicy(); policy.Origins.Add(CorsConstants.AnyOrigin); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.Empty(result.AllowedExposedHeaders); }
public void ApplyResult_PreflightMaxAge_MaxAgeHeaderAdded() { // Arrange var result = new CorsResult { PreflightMaxAge = TimeSpan.FromSeconds(30) }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("30", httpContext.Response.Headers["Access-Control-Max-Age"]); }
public void ApplyResult_OneAllowExposedHeaders_ExposedHeadersHeaderAdded() { // Arrange var result = new CorsResult(); result.AllowedExposedHeaders.Add("foo"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("foo", httpContext.Response.Headers["Access-Control-Expose-Headers"]); }
public void EvaluatePolicy_PreflightRequest_MethodNotAllowed_ReturnsInvalidResult() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(method: "OPTIONS", origin: "http://example.com", accessControlRequestMethod: "PUT"); var policy = new CorsPolicy(); policy.Origins.Add(CorsConstants.AnyOrigin); policy.Methods.Add("GET"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.Empty(result.AllowedMethods); }
public void ApplyResult_OneAllowMethods_AllowMethodsHeaderAdded() { // Arrange var result = new CorsResult(); result.AllowedMethods.Add("PUT"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("PUT", httpContext.Response.Headers["Access-Control-Allow-Methods"]); }
public void ApplyResult_NoAllowExposedHeaders_ExposedHeadersHeaderNotAdded() { // Arrange var result = new CorsResult { // AllowExposedHeaders is empty by default }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Expose-Headers", httpContext.Response.Headers.Keys); }
public void ApplyResult_AddVaryHeader_VaryHeaderAdded() { // Arrange var result = new CorsResult { VaryByOrigin = true }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("Origin", httpContext.Response.Headers["Vary"]); }
public void ApplyResult_NoAllowCredentials_AllowCredentialsHeaderNotAdded() { // Arrange var result = new CorsResult { SupportsCredentials = false }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Allow-Credentials", httpContext.Response.Headers.Keys); }
public void ApplyResult_NoAllowOrigin_AllowOriginHeaderNotAdded() { // Arrange var result = new CorsResult { AllowedOrigin = null }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Allow-Origin", httpContext.Response.Headers.Keys); }
public void EvaluatePolicy_LoggingForNonPreflightRequests_HasOriginHeader_PolicySucceeded() { var sink = new TestSink(); var loggerFactory = new TestLoggerFactory(sink, enabled: true); var corsService = new CorsService(new TestCorsOptions(), loggerFactory); var requestContext = GetHttpContext(origin: "http://allowed.example.com"); var policy = new CorsPolicy(); policy.Origins.Add("http://allowed.example.com"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); Assert.Equal("The request has an origin header: 'http://allowed.example.com'.", sink.Writes[0].State.ToString()); Assert.Equal("Policy execution successful.", sink.Writes[1].State.ToString()); }
public void ApplyResult_AllowOrigin_AllowOriginHeaderAdded() { // Arrange var result = new CorsResult { AllowedOrigin = "http://example.com" }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("http://example.com", httpContext.Response.Headers["Access-Control-Allow-Origin"]); }
public void ApplyResult_NoPreflightMaxAge_MaxAgeHeaderNotAdded() { // Arrange var result = new CorsResult { PreflightMaxAge = null }; var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Max-Age", httpContext.Response.Headers.Keys); }
public void EvaluatePolicy_MultiOriginsPolicy_ReturnsVaryByOriginHeader() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(origin: "http://example.com"); var policy = new CorsPolicy(); policy.Origins.Add("http://example.com"); policy.Origins.Add("http://example-two.com"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.NotNull(result.AllowedOrigin); Assert.True(result.VaryByOrigin); }
public void EvaluatePolicy_OneExposedHeaders_HeadersAllowed() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(origin: "http://example.com"); var policy = new CorsPolicy(); policy.Origins.Add(CorsConstants.AnyOrigin); policy.ExposedHeaders.Add("foo"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.Equal(1, result.AllowedExposedHeaders.Count); Assert.Contains("foo", result.AllowedExposedHeaders); }
public async Task Invoke_WithCustomPolicyProviderThatReturnsAsynchronously_Works() { // Arrange var corsService = new CorsService(Options.Create(new CorsOptions()), NullLoggerFactory.Instance); var mockProvider = new Mock <ICorsPolicyProvider>(); var loggerFactory = NullLoggerFactory.Instance; var policy = new CorsPolicyBuilder() .WithOrigins(OriginUrl) .WithHeaders("AllowedHeader") .Build(); mockProvider.Setup(o => o.GetPolicyAsync(It.IsAny <HttpContext>(), It.IsAny <string>())) .ReturnsAsync(policy, TimeSpan.FromMilliseconds(10)); var middleware = new CorsMiddleware( Mock.Of <RequestDelegate>(), corsService, loggerFactory, "DefaultPolicyName"); var httpContext = new DefaultHttpContext(); httpContext.Request.Method = "OPTIONS"; httpContext.Request.Headers.Add(CorsConstants.Origin, new[] { OriginUrl }); httpContext.Request.Headers.Add(CorsConstants.AccessControlRequestMethod, new[] { "PUT" }); // Act await middleware.Invoke(httpContext, mockProvider.Object); // Assert var response = httpContext.Response; Assert.Collection( response.Headers.OrderBy(o => o.Key), kvp => { Assert.Equal(CorsConstants.AccessControlAllowHeaders, kvp.Key); Assert.Equal("AllowedHeader", Assert.Single(kvp.Value)); }, kvp => { Assert.Equal(CorsConstants.AccessControlAllowOrigin, kvp.Key); Assert.Equal(OriginUrl, Assert.Single(kvp.Value)); }); }
public void ApplyResult_AllowCredentials_AllowCredentialsHeaderAdded() { // Arrange var result = new CorsResult { SupportsCredentials = true }; var service = new CorsService(new TestCorsOptions()); // Act var httpContext = new DefaultHttpContext(); service.ApplyResult(result, httpContext.Response); // Assert Assert.Equal("true", httpContext.Response.Headers["Access-Control-Allow-Credentials"]); }
public void ApplyResult_SimpleAllowMethods_AllowMethodsHeaderNotAdded() { // Arrange var result = new CorsResult(); result.AllowedMethods.Add("GET"); result.AllowedMethods.Add("HEAD"); result.AllowedMethods.Add("POST"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Allow-Methods", httpContext.Response.Headers.Keys); }
public void EvaluatePolicy_LoggingForPreflightRequests_DoesNotHaveOriginHeader() { var sink = new TestSink(); var loggerFactory = new TestLoggerFactory(sink, enabled: true); var corsService = new CorsService(new TestCorsOptions(), loggerFactory); var requestContext = GetHttpContext(method: "OPTIONS", origin: null, accessControlRequestMethod: "PUT"); var policy = new CorsPolicy(); policy.Origins.Add("http://allowed.example.com"); policy.Methods.Add("PUT"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); Assert.Equal("The request is a preflight request.", sink.Writes[0].State.ToString()); Assert.Equal("The request does not have an origin header.", sink.Writes[1].State.ToString()); }
public void EvaluatePolicy_SupportsCredentials_AllowCredentialsReturnsTrue() { // Arrange var corsService = new CorsService(new TestCorsOptions()); var requestContext = GetHttpContext(origin: "http://example.com"); var policy = new CorsPolicy { SupportsCredentials = true }; policy.Origins.Add(CorsConstants.AnyOrigin); // Act var result = corsService.EvaluatePolicy(requestContext, policy); // Assert Assert.True(result.SupportsCredentials); }
public void EvaluatePolicy_LoggingForNonPreflightRequests_DoesNotHaveOriginHeader() { var sink = new TestSink(); var loggerFactory = new TestLoggerFactory(sink, enabled: true); var corsService = new CorsService(new TestCorsOptions(), loggerFactory); var requestContext = GetHttpContext(origin: null); var policy = new CorsPolicy(); policy.Origins.Add("http://allowed.example.com"); // Act var result = corsService.EvaluatePolicy(requestContext, policy); var logMessage = Assert.Single(sink.Writes); Assert.Equal("The request does not have an origin header.", logMessage.State.ToString()); }
public void ApplyResult_SimpleAllowHeaders_AllowHeadersHeaderNotAdded() { // Arrange var result = new CorsResult(); result.AllowedHeaders.Add("Accept"); result.AllowedHeaders.Add("Accept-Language"); result.AllowedHeaders.Add("Content-Language"); var httpContext = new DefaultHttpContext(); var service = new CorsService(new TestCorsOptions()); // Act service.ApplyResult(result, httpContext.Response); // Assert Assert.DoesNotContain("Access-Control-Allow-Headers", httpContext.Response.Headers.Keys); }