public void Constructor_WithPolicy_AddsTheGivenPolicy()
        {
            // Arrange
            var originalPolicy = new CorsPolicy();
            originalPolicy.Origins.Add("http://existing.com");
            originalPolicy.Headers.Add("Existing");
            originalPolicy.Methods.Add("GET");
            originalPolicy.ExposedHeaders.Add("ExistingExposed");
            originalPolicy.SupportsCredentials = true;
            originalPolicy.PreflightMaxAge = TimeSpan.FromSeconds(12);

            // Act
            var builder = new CorsPolicyBuilder(originalPolicy);

            // Assert
            var corsPolicy = builder.Build();

            Assert.False(corsPolicy.AllowAnyHeader);
            Assert.False(corsPolicy.AllowAnyMethod);
            Assert.False(corsPolicy.AllowAnyOrigin);
            Assert.True(corsPolicy.SupportsCredentials);
            Assert.NotSame(originalPolicy.Headers, corsPolicy.Headers);
            Assert.Equal(originalPolicy.Headers, corsPolicy.Headers);
            Assert.NotSame(originalPolicy.Methods, corsPolicy.Methods);
            Assert.Equal(originalPolicy.Methods, corsPolicy.Methods);
            Assert.NotSame(originalPolicy.Origins, corsPolicy.Origins);
            Assert.Equal(originalPolicy.Origins, corsPolicy.Origins);
            Assert.NotSame(originalPolicy.ExposedHeaders, corsPolicy.ExposedHeaders);
            Assert.Equal(originalPolicy.ExposedHeaders, corsPolicy.ExposedHeaders);
            Assert.Equal(TimeSpan.FromSeconds(12), corsPolicy.PreflightMaxAge);
        }
Exemple #2
0
        /// <inheritdoc />
        public CorsResult EvaluatePolicy(HttpContext context, CorsPolicy policy)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            var corsResult = new CorsResult();
            var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod];
            if (string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.Ordinal) &&
                !StringValues.IsNullOrEmpty(accessControlRequestMethod))
            {
                EvaluatePreflightRequest(context, policy, corsResult);
            }
            else
            {
                EvaluateRequest(context, policy, corsResult);
            }

            return corsResult;
        }
Exemple #3
0
        public virtual void EvaluateRequest(HttpContext context, CorsPolicy policy, CorsResult result)
        {
            var origin = context.Request.Headers[CorsConstants.Origin];
            if (StringValues.IsNullOrEmpty(origin) || !policy.AllowAnyOrigin && !policy.Origins.Contains(origin))
            {
                return;
            }

            AddOriginToResult(origin, policy, result);
            result.SupportsCredentials = policy.SupportsCredentials;
            AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders);
        }
Exemple #4
0
        /// <summary>
        /// Adds a new policy.
        /// </summary>
        /// <param name="name">The name of the policy.</param>
        /// <param name="policy">The <see cref="CorsPolicy"/> policy to be added.</param>
        public void AddPolicy(string name, CorsPolicy policy)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            PolicyMap[name] = policy;
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDataProtection();

            //Set up CORS
            var policy = new CorsPolicy();

            policy.Headers.Add("*");
            policy.Methods.Add("*");
            policy.Origins.Add("*");
            policy.SupportsCredentials = true;

            services.AddCors(x => x.AddPolicy("corsGlobalPolicy", policy));
        }
Exemple #7
0
        public void Default_Constructor()
        {
            // Arrange & Act
            var corsPolicy = new CorsPolicy();

            // Assert
            Assert.False(corsPolicy.AllowAnyHeader);
            Assert.False(corsPolicy.AllowAnyMethod);
            Assert.False(corsPolicy.AllowAnyOrigin);
            Assert.False(corsPolicy.SupportsCredentials);
            Assert.Empty(corsPolicy.ExposedHeaders);
            Assert.Empty(corsPolicy.Headers);
            Assert.Empty(corsPolicy.Methods);
            Assert.Empty(corsPolicy.Origins);
            Assert.Null(corsPolicy.PreflightMaxAge);
        }
Exemple #8
0
        public void SettingNegativePreflightMaxAge_Throws()
        {
            // Arrange
            var policy = new CorsPolicy();

            // Act
            var exception = Assert.Throws<ArgumentOutOfRangeException>(() =>
            {
                policy.PreflightMaxAge = TimeSpan.FromSeconds(-12);
            });

            // Assert
            Assert.Equal(
                $"PreflightMaxAge must be greater than or equal to 0.{Environment.NewLine}Parameter name: value",
                exception.Message);
        }
Exemple #9
0
        public void EvaluatePolicy_AllowAnyOrigin_DoesNotSupportCredentials_EmitsWildcardForOrigin()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());
            var requestContext = GetHttpContext(origin: "http://example.com");

            var policy = new CorsPolicy
            {
                SupportsCredentials = false
            };

            policy.Origins.Add(CorsConstants.AnyOrigin);

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal("*", result.AllowedOrigin);
        }
        public async Task GetsNamedPolicy(string policyName)
        {
            // Arrange
            var options = new CorsOptions();
            var policy = new CorsPolicy();
            options.AddPolicy(policyName, policy);

            var corsOptions = new TestCorsOptions
            {
                Value = options
            };
            var policyProvider = new DefaultCorsPolicyProvider(corsOptions);

            // Act 
            var actualPolicy = await policyProvider.GetPolicyAsync(new DefaultHttpContext(), policyName);

            // Assert
            Assert.Same(policy, actualPolicy);
        }
        public async Task PreFlight_MatchesPolicy_SetsResponseHeaders()
        {
            // Arrange
            var policy = new CorsPolicy();
            policy.Origins.Add("http://localhost:5001");
            policy.Methods.Add("PUT");
            policy.Headers.Add("Header1");
            policy.ExposedHeaders.Add("AllowedHeader");

            var appBuilder = new WebApplicationBuilder()
                .Configure(app =>
                {
                    app.UseCors("customPolicy");
                    app.Run(async context =>
                    {
                        await context.Response.WriteAsync("Cross origin response");
                    });
                })
                .ConfigureServices(services =>
                {
                    services.AddCors(options =>
                    {
                        options.AddPolicy("customPolicy", policy);
                    });
                });

            using (var server = new TestServer(appBuilder))
            {
                // Act
                // Preflight request.
                var response = await server.CreateRequest("/")
                    .AddHeader(CorsConstants.Origin, "http://localhost:5001")
                    .AddHeader(CorsConstants.AccessControlRequestMethod, "PUT")
                    .SendAsync(CorsConstants.PreflightHttpMethod);

                // Assert
                response.EnsureSuccessStatusCode();
                Assert.Equal(2, response.Headers.Count());
                Assert.Equal("http://localhost:5001", response.Headers.GetValues(CorsConstants.AccessControlAllowOrigin).FirstOrDefault());
                Assert.Equal("PUT", response.Headers.GetValues(CorsConstants.AccessControlAllowMethods).FirstOrDefault());
            }
        }
        public void ConstructorWithPolicy_HavingNullPreflightMaxAge_AddsTheGivenPolicy()
        {
            // Arrange
            var originalPolicy = new CorsPolicy();
            originalPolicy.Origins.Add("http://existing.com");

            // Act
            var builder = new CorsPolicyBuilder(originalPolicy);

            // Assert
            var corsPolicy = builder.Build();

            Assert.Null(corsPolicy.PreflightMaxAge);
            Assert.False(corsPolicy.AllowAnyHeader);
            Assert.False(corsPolicy.AllowAnyMethod);
            Assert.False(corsPolicy.AllowAnyOrigin);
            Assert.NotSame(originalPolicy.Origins, corsPolicy.Origins);
            Assert.Equal(originalPolicy.Origins, corsPolicy.Origins);
            Assert.Empty(corsPolicy.Headers);
            Assert.Empty(corsPolicy.Methods);
            Assert.Empty(corsPolicy.ExposedHeaders);
        }
Exemple #13
0
        public void ToString_ReturnsThePropertyValues()
        {
            // Arrange
            var corsPolicy = new CorsPolicy
            {
                PreflightMaxAge = TimeSpan.FromSeconds(12),
                SupportsCredentials = true
            };
            corsPolicy.Headers.Add("foo");
            corsPolicy.Headers.Add("bar");
            corsPolicy.Origins.Add("http://example.com");
            corsPolicy.Origins.Add("http://example.org");
            corsPolicy.Methods.Add("GET");

            // Act
            var policyString = corsPolicy.ToString();

            // Assert
            Assert.Equal(
                @"AllowAnyHeader: False, AllowAnyMethod: False, AllowAnyOrigin: False, PreflightMaxAge: 12,"+
                " SupportsCredentials: True, Origins: {http://example.com,http://example.org}, Methods: {GET},"+
                " Headers: {foo,bar}, ExposedHeaders: {}",
                policyString);
        }
Exemple #14
0
        /// <summary>
        /// Instantiates a new <see cref="CorsMiddleware"/>.
        /// </summary>
        /// <param name="next">The next middleware in the pipeline.</param>
        /// <param name="corsService">An instance of <see cref="ICorsService"/>.</param>
        /// <param name="policy">An instance of the <see cref="CorsPolicy"/> which can be applied.</param>
        public CorsMiddleware(
           RequestDelegate next,
           ICorsService corsService,
           CorsPolicy policy)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            if (corsService == null)
            {
                throw new ArgumentNullException(nameof(corsService));
            }

            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            _next = next;
            _corsService = corsService;
            _policy = policy;
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        public void EvaluatePolicy_PreflightRequest_SupportsCredentials_AllowCredentialsReturnsTrue()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());
            var requestContext = GetHttpContext(method: "OPTIONS", origin: "http://example.com", accessControlRequestMethod: "PUT");
            var policy = new CorsPolicy
            {
                SupportsCredentials = true
            };
            policy.Origins.Add(CorsConstants.AnyOrigin);
            policy.Methods.Add("*");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.True(result.SupportsCredentials);
        }
Exemple #17
0
        public virtual void EvaluatePreflightRequest(HttpContext context, CorsPolicy policy, CorsResult result)
        {
            var origin = context.Request.Headers[CorsConstants.Origin];
            if (StringValues.IsNullOrEmpty(origin) || !policy.AllowAnyOrigin && !policy.Origins.Contains(origin))
            {
                return;
            }

            var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod];
            if (StringValues.IsNullOrEmpty(accessControlRequestMethod))
            {
                return;
            }

            var requestHeaders =
                context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestHeaders);

            if (!policy.AllowAnyMethod && !policy.Methods.Contains(accessControlRequestMethod))
            {
                return;
            }

            if (!policy.AllowAnyHeader &&
                requestHeaders != null &&
                !requestHeaders.All(header => CorsConstants.SimpleRequestHeaders.Contains(header, StringComparer.OrdinalIgnoreCase) ||
                                              policy.Headers.Contains(header, StringComparer.OrdinalIgnoreCase)))
            {
                return;
            }

            AddOriginToResult(origin, policy, result);
            result.SupportsCredentials = policy.SupportsCredentials;
            result.PreflightMaxAge = policy.PreflightMaxAge;
            result.AllowedMethods.Add(accessControlRequestMethod);
            AddHeaderValues(result.AllowedHeaders, requestHeaders);
        }
Exemple #18
0
        public void EvaluatePolicy_PreflightRequest_PreflightMaxAge_PreflightMaxAgeSet()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());
            var requestContext = GetHttpContext(method: "OPTIONS", origin: "http://example.com", accessControlRequestMethod: "PUT");
            var policy = new CorsPolicy
            {
                PreflightMaxAge = TimeSpan.FromSeconds(10)
            };
            policy.Origins.Add(CorsConstants.AnyOrigin);
            policy.Methods.Add("*");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal(TimeSpan.FromSeconds(10), result.PreflightMaxAge);
        }
Exemple #19
0
        public void TryValidateOrigin_DoesCaseSensitiveComparison()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());

            var policy = new CorsPolicy();
            policy.Origins.Add("http://Example.com");
            var httpContext = GetHttpContext(origin: "http://example.com");

            // Act
            var result = corsService.EvaluatePolicy(httpContext, policy);

            // Assert
            Assert.Empty(result.AllowedHeaders);
            Assert.Empty(result.AllowedMethods);
            Assert.Empty(result.AllowedExposedHeaders);
            Assert.Null(result.AllowedOrigin);
        }
Exemple #20
0
 /// <summary>
 /// Creates a new instance of the <see cref="CorsPolicyBuilder"/>.
 /// </summary>
 /// <param name="policy">The policy which will be used to intialize the builder.</param>
 public CorsPolicyBuilder(CorsPolicy policy)
 {
     Combine(policy);
 }
Exemple #21
0
        /// <summary>
        /// Combines the given <paramref name="policy"/> to the existing properties in the builder.
        /// </summary>
        /// <param name="policy">The policy which needs to be combined.</param>
        /// <returns>The current policy builder</returns>
        private CorsPolicyBuilder Combine(CorsPolicy policy)
        {
            if (policy == null)
            {
                throw new ArgumentNullException(nameof(policy));
            }

            WithOrigins(policy.Origins.ToArray());
            WithHeaders(policy.Headers.ToArray());
            WithExposedHeaders(policy.ExposedHeaders.ToArray());
            WithMethods(policy.Methods.ToArray());

            if (policy.PreflightMaxAge.HasValue)
            {
                SetPreflightMaxAge(policy.PreflightMaxAge.Value);
            }

            if (policy.SupportsCredentials)
            {
                AllowCredentials();
            }
            else
            {
                DisallowCredentials();
            }

            return this;
        }
Exemple #22
0
        public void EvaluatePolicy_PreflightRequest_HeadersRequested_AllowAllHeaders_ReturnsRequestedHeaders()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());
            var requestContext = GetHttpContext(
                method: "OPTIONS",
                origin: "http://example.com",
                accessControlRequestMethod: "PUT",
                accessControlRequestHeaders: new[] { "foo", "bar" });
            var policy = new CorsPolicy();
            policy.Origins.Add(CorsConstants.AnyOrigin);
            policy.Methods.Add("*");
            policy.Headers.Add("*");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal(2, result.AllowedHeaders.Count);
            Assert.Contains("foo", result.AllowedHeaders);
            Assert.Contains("bar", result.AllowedHeaders);
        }
Exemple #23
0
        public void EvaluatePolicy_PreflightRequest_HeadersRequested_AllowSomeHeaders_ReturnsSubsetOfListedHeaders()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());
            var requestContext = GetHttpContext(
                method: "OPTIONS",
                origin: "http://example.com",
                accessControlRequestMethod: "PUT",
                accessControlRequestHeaders: new[] { "content-type", "accept" });
            var policy = new CorsPolicy();
            policy.Origins.Add(CorsConstants.AnyOrigin);
            policy.Methods.Add("*");
            policy.Headers.Add("foo");
            policy.Headers.Add("bar");
            policy.Headers.Add("Content-Type");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal(2, result.AllowedHeaders.Count);
            Assert.Contains("Content-Type", result.AllowedHeaders, StringComparer.OrdinalIgnoreCase);
        }
Exemple #24
0
        public void EvaluatePolicy_AllowAnyOrigin_SupportsCredentials_AddsSpecificOrigin()
        {
            // 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.Equal("http://example.com", result.AllowedOrigin);
            Assert.True(result.VaryByOrigin);
        }
Exemple #25
0
        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);
        }
Exemple #26
0
        public void EvaluatePolicy_ManyExposedHeaders_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");
            policy.ExposedHeaders.Add("bar");
            policy.ExposedHeaders.Add("baz");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal(3, result.AllowedExposedHeaders.Count);
            Assert.Contains("foo", result.AllowedExposedHeaders);
            Assert.Contains("bar", result.AllowedExposedHeaders);
            Assert.Contains("baz", result.AllowedExposedHeaders);
        }
Exemple #27
0
 private void AddOriginToResult(string origin, CorsPolicy policy, CorsResult result)
 {
     if (policy.AllowAnyOrigin)
     {
         if (policy.SupportsCredentials)
         {
             result.AllowedOrigin = origin;
             result.VaryByOrigin = true;
         }
         else
         {
             result.AllowedOrigin = CorsConstants.AnyOrigin;
         }
     }
     else if (policy.Origins.Contains(origin))
     {
         result.AllowedOrigin = origin;
     }
 }
Exemple #28
0
        public void EvaluatePolicy_PreflightRequest_ListedMethod_ReturnsSubsetOfListedMethods()
        {
            // 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("PUT");
            policy.Methods.Add("DELETE");

            // Act
            var result = corsService.EvaluatePolicy(requestContext, policy);

            // Assert
            Assert.Equal(1, result.AllowedMethods.Count);
            Assert.Contains("PUT", result.AllowedMethods);
        }
Exemple #29
0
        // This method gets called by a runtime.
        // Use this method to add services to the container
        public void ConfigureServices(IServiceCollection services)
        {
            var cacheStore = new CacheStore();

            //CORS -- temporary currently allow anyone to connect
            var OpenBookAPIcors = new CorsPolicy();
            OpenBookAPIcors.Headers.Add("*");
            OpenBookAPIcors.Origins.Add("*");
            OpenBookAPIcors.Methods.Add("*");
            OpenBookAPIcors.SupportsCredentials = true;
            services.AddCors(cors => cors.AddPolicy("OpenBookAPI", OpenBookAPIcors));

            //Dependancy Injection
            Modules.Register(services);
            services.AddInstance(typeof(IConfiguration),Configuration);
            services.AddInstance(typeof(ICacheStore), cacheStore);
            services.AddSingleton<HttpCacheActionFilter>();
            services.AddInstance<IRouter>(_router);
            services.AddInstance<Serilog.ILogger>(Log.Logger);

            //Swagger
            services.AddSwagger();
            services.ConfigureSwaggerDocument(options =>
            {
                options.SingleApiVersion(new Info
                {
                    Version = "v1",
                    Title = "OpenBook API",
                    Description = "The API Backend for the OpenBookApp",
                    TermsOfService = "No Potatos.",
                });

            });

            services.AddSignalR(options =>
            {
                options.Hubs.EnableDetailedErrors = true;
            });

            services.AddMvc(options =>
            {
                options.Filters.Add(typeof(GlobalExceptionFilter));
                options.Filters.Add(typeof(HttpCacheActionFilter)); //new HttpCacheActionFilter(cacheStore, Log.Logger));
            });
        }
Exemple #30
0
        public void EaluatePolicy_DoesCaseSensitiveComparison()
        {
            // Arrange
            var corsService = new CorsService(new TestCorsOptions());

            var policy = new CorsPolicy();
            policy.Methods.Add("POST");
            var httpContext = GetHttpContext(origin: null, accessControlRequestMethod: "post");

            // Act
            var result = corsService.EvaluatePolicy(httpContext, policy);

            // Assert
            Assert.Empty(result.AllowedHeaders);
            Assert.Empty(result.AllowedMethods);
            Assert.Empty(result.AllowedExposedHeaders);
            Assert.Null(result.AllowedOrigin);
        }