From 8214954d5b0dafe191890da9a3de86f5b607ea69 Mon Sep 17 00:00:00 2001 From: Choc Date: Tue, 1 Nov 2016 15:31:05 -0700 Subject: [PATCH] Add support for clients to configure a policy with custom logic about whether an origin should be allowed and provide a default implementation of the functionality to allow wildcard subdomains --- .gitignore | 1 + .../Infrastructure/CorsPolicy.cs | 19 ++++++ .../Infrastructure/CorsPolicyBuilder.cs | 46 +++++++++---- .../Infrastructure/CorsPolicyExtensions.cs | 31 +++++++++ .../Infrastructure/CorsService.cs | 42 ++++++------ .../Infrastructure/UriHelpers.cs | 19 ++++++ .../Properties/AssemblyInfo.cs | 2 + .../CorsPolicyBuilderTests.cs | 32 +++++++++ .../CorsPolicyExtensionsTests.cs | 65 ++++++++++++++++++ .../CorsPolicyTests.cs | 1 + .../CorsServiceTests.cs | 42 ++++++++++++ .../UriHelpersTests.cs | 66 +++++++++++++++++++ .../project.json | 3 + .../CorsMiddlewareWebSite/project.json | 3 +- 14 files changed, 339 insertions(+), 33 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyExtensions.cs create mode 100644 src/Microsoft.AspNetCore.Cors/Infrastructure/UriHelpers.cs create mode 100644 test/Microsoft.AspNetCore.Cors.Test/CorsPolicyExtensionsTests.cs create mode 100644 test/Microsoft.AspNetCore.Cors.Test/UriHelpersTests.cs diff --git a/.gitignore b/.gitignore index 5daa6eed09..cecfac6cc7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ node_modules *launchSettings.json .build/ .testPublish/ +.vscode diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicy.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicy.cs index b1fc25a939..f541863c69 100644 --- a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicy.cs +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicy.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace Microsoft.AspNetCore.Cors.Infrastructure @@ -14,6 +15,14 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure { private TimeSpan? _preflightMaxAge; + /// + /// Default constructor for a CorsPolicy. + /// + public CorsPolicy() + { + IsOriginAllowed = DefaultIsOriginAllowed; + } + /// /// Gets a value indicating if all headers are allowed. /// @@ -62,6 +71,11 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure } } + /// + /// Gets or sets a function which evaluates whether an origin is allowed. + /// + public Func IsOriginAllowed { get; set; } + /// /// Gets the headers that the resource might use and can be exposed. /// @@ -141,5 +155,10 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure builder.Append("}"); return builder.ToString(); } + + private bool DefaultIsOriginAllowed(string origin) + { + return Origins.Contains(origin, StringComparer.Ordinal); + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyBuilder.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyBuilder.cs index ed20996e5e..88e16fa0fa 100644 --- a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyBuilder.cs +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyBuilder.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// Adds the specified to the policy. /// /// The origins that are allowed. - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder WithOrigins(params string[] origins) { foreach (var req in origins) @@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// Adds the specified to the policy. /// /// The headers which need to be allowed in the request. - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder WithHeaders(params string[] headers) { foreach (var req in headers) @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// Adds the specified to the policy. /// /// The headers which need to be exposed to the client. - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder WithExposedHeaders(params string[] exposedHeaders) { foreach (var req in exposedHeaders) @@ -79,7 +79,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// Adds the specified to the policy. /// /// The methods which need to be added to the policy. - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder WithMethods(params string[] methods) { foreach (var req in methods) @@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// Sets the policy to allow credentials. /// - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder AllowCredentials() { _policy.SupportsCredentials = true; @@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// Sets the policy to not allow credentials. /// - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder DisallowCredentials() { _policy.SupportsCredentials = false; @@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// Ensures that the policy allows any origin. /// - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder AllowAnyOrigin() { _policy.Origins.Clear(); @@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// Ensures that the policy allows any method. /// - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder AllowAnyMethod() { _policy.Methods.Clear(); @@ -135,7 +135,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// Ensures that the policy allows any header. /// - /// The current policy builder + /// The current policy builder. public CorsPolicyBuilder AllowAnyHeader() { _policy.Headers.Clear(); @@ -148,13 +148,36 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// /// A positive indicating the time a preflight /// request can be cached. - /// + /// The current policy builder. public CorsPolicyBuilder SetPreflightMaxAge(TimeSpan preflightMaxAge) { _policy.PreflightMaxAge = preflightMaxAge; return this; } + /// + /// Sets the specified for the underlying policy. + /// + /// The function used by the policy to evaluate if an origin is allowed. + /// The current policy builder. + public CorsPolicyBuilder SetIsOriginAllowed(Func isOriginAllowed) + { + _policy.IsOriginAllowed = isOriginAllowed; + return this; + } + + /// + /// Sets the property of the policy to be a function + /// that allows origins to match a configured wildcarded domain when evaluating if the + /// origin is allowed. + /// + /// The current policy builder. + public CorsPolicyBuilder SetIsOriginAllowedToAllowWildcardSubdomains() + { + _policy.IsOriginAllowed = _policy.IsOriginAnAllowedSubdomain; + return this; + } + /// /// Builds a new using the entries added. /// @@ -168,7 +191,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure /// Combines the given to the existing properties in the builder. /// /// The policy which needs to be combined. - /// The current policy builder + /// The current policy builder. private CorsPolicyBuilder Combine(CorsPolicy policy) { if (policy == null) @@ -180,6 +203,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure WithHeaders(policy.Headers.ToArray()); WithExposedHeaders(policy.ExposedHeaders.ToArray()); WithMethods(policy.Methods.ToArray()); + SetIsOriginAllowed(policy.IsOriginAllowed); if (policy.PreflightMaxAge.HasValue) { diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyExtensions.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyExtensions.cs new file mode 100644 index 0000000000..deae787231 --- /dev/null +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsPolicyExtensions.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; + +namespace Microsoft.AspNetCore.Cors.Infrastructure +{ + internal static class CorsPolicyExtensions + { + private const string _WildcardSubdomain = "*."; + + public static bool IsOriginAnAllowedSubdomain(this CorsPolicy policy, string origin) + { + if (policy.Origins.Contains(origin)) + { + return true; + } + var originUri = new Uri(origin, UriKind.Absolute); + return policy.Origins + .Where(o => o.Contains($"://{_WildcardSubdomain}")) + .Select(CreateDomainUri) + .Any(domain => UriHelpers.IsSubdomainOf(originUri, domain)); + } + + private static Uri CreateDomainUri(string origin) + { + return new Uri(origin.Replace(_WildcardSubdomain, string.Empty), UriKind.Absolute); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs index 483cb3e59a..bd978495fb 100644 --- a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs @@ -97,17 +97,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public virtual void EvaluateRequest(HttpContext context, CorsPolicy policy, CorsResult result) { var origin = context.Request.Headers[CorsConstants.Origin]; - if (StringValues.IsNullOrEmpty(origin)) + if (!IsOriginAllowed(policy, origin)) { - _logger?.RequestDoesNotHaveOriginHeader(); - return; - } - - _logger?.RequestHasOriginHeader(origin); - if (!policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) - { - _logger?.PolicyFailure(); - _logger?.OriginNotAllowed(origin); return; } @@ -120,17 +111,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public virtual void EvaluatePreflightRequest(HttpContext context, CorsPolicy policy, CorsResult result) { var origin = context.Request.Headers[CorsConstants.Origin]; - if (StringValues.IsNullOrEmpty(origin)) + if (!IsOriginAllowed(policy, origin)) { - _logger?.RequestDoesNotHaveOriginHeader(); - return; - } - - _logger?.RequestHasOriginHeader(origin); - if (!policy.AllowAnyOrigin && !policy.Origins.Contains(origin)) - { - _logger?.PolicyFailure(); - _logger?.OriginNotAllowed(origin); return; } @@ -286,7 +268,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure result.AllowedOrigin = CorsConstants.AnyOrigin; } } - else if (policy.Origins.Contains(origin)) + else if (policy.IsOriginAllowed(origin)) { result.AllowedOrigin = origin; } @@ -304,5 +286,23 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure target.Add(current); } } + + private bool IsOriginAllowed(CorsPolicy policy, StringValues origin) + { + if (StringValues.IsNullOrEmpty(origin)) + { + _logger?.RequestDoesNotHaveOriginHeader(); + return false; + } + + _logger?.RequestHasOriginHeader(origin); + if (policy.AllowAnyOrigin || policy.IsOriginAllowed(origin)) + { + return true; + } + _logger?.PolicyFailure(); + _logger?.OriginNotAllowed(origin); + return false; + } } } diff --git a/src/Microsoft.AspNetCore.Cors/Infrastructure/UriHelpers.cs b/src/Microsoft.AspNetCore.Cors/Infrastructure/UriHelpers.cs new file mode 100644 index 0000000000..6c420e9260 --- /dev/null +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/UriHelpers.cs @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNetCore.Cors.Infrastructure +{ + internal static class UriHelpers + { + public static bool IsSubdomainOf(Uri subdomain, Uri domain) + { + return subdomain.IsAbsoluteUri + && domain.IsAbsoluteUri + && subdomain.Scheme == domain.Scheme + && subdomain.Port == domain.Port + && subdomain.Host.EndsWith($".{domain.Host}", StringComparison.Ordinal); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Cors/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.Cors/Properties/AssemblyInfo.cs index e3ae91c58b..f7279b13b1 100644 --- a/src/Microsoft.AspNetCore.Cors/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNetCore.Cors/Properties/AssemblyInfo.cs @@ -3,9 +3,11 @@ using System.Reflection; using System.Resources; +using System.Runtime.CompilerServices; [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: AssemblyCompany("Microsoft Corporation.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyProduct("Microsoft ASP.NET Core")] +[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Cors.Test,PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyBuilderTests.cs b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyBuilderTests.cs index 0ee3b7e524..8a223ad225 100644 --- a/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyBuilderTests.cs +++ b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyBuilderTests.cs @@ -14,6 +14,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure public void Constructor_WithPolicy_AddsTheGivenPolicy() { // Arrange + Func isOriginAllowed = origin => true; var originalPolicy = new CorsPolicy(); originalPolicy.Origins.Add("http://existing.com"); originalPolicy.Headers.Add("Existing"); @@ -21,6 +22,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure originalPolicy.ExposedHeaders.Add("ExistingExposed"); originalPolicy.SupportsCredentials = true; originalPolicy.PreflightMaxAge = TimeSpan.FromSeconds(12); + originalPolicy.IsOriginAllowed = isOriginAllowed; // Act var builder = new CorsPolicyBuilder(originalPolicy); @@ -41,6 +43,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.NotSame(originalPolicy.ExposedHeaders, corsPolicy.ExposedHeaders); Assert.Equal(originalPolicy.ExposedHeaders, corsPolicy.ExposedHeaders); Assert.Equal(TimeSpan.FromSeconds(12), corsPolicy.PreflightMaxAge); + Assert.Same(originalPolicy.IsOriginAllowed, corsPolicy.IsOriginAllowed); } [Fact] @@ -140,6 +143,35 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.Equal(new List() { "*" }, corsPolicy.Origins); } + [Fact] + public void SetIsOriginAllowed_AddsIsOriginAllowed() + { + // Arrange + var builder = new CorsPolicyBuilder(); + Func isOriginAllowed = origin => true; + + // Act + builder.SetIsOriginAllowed(isOriginAllowed); + + // Assert + var corsPolicy = builder.Build(); + Assert.Same(corsPolicy.IsOriginAllowed, isOriginAllowed); + } + + [Fact] + public void SetIsOriginAllowedToAllowWildcardSubdomains_AllowsWildcardSubdomains() + { + // Arrange + var builder = new CorsPolicyBuilder("http://*.example.com"); + + // Act + builder.SetIsOriginAllowedToAllowWildcardSubdomains(); + + // Assert + var corsPolicy = builder.Build(); + Assert.True(corsPolicy.IsOriginAllowed("http://test.example.com")); + } + [Fact] public void WithMethods_AddsMethods() { diff --git a/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyExtensionsTests.cs b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyExtensionsTests.cs new file mode 100644 index 0000000000..2c323162ca --- /dev/null +++ b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyExtensionsTests.cs @@ -0,0 +1,65 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Xunit; + +namespace Microsoft.AspNetCore.Cors.Infrastructure +{ + public sealed class CorsPolicyExtensionsTest + { + [Fact] + public void IsOriginAnAllowedSubdomain_ReturnsTrueIfPolicyContainsOrigin() + { + // Arrange + const string origin = "http://sub.domain"; + var policy = new CorsPolicy(); + policy.Origins.Add(origin); + + // Act + var actual = policy.IsOriginAnAllowedSubdomain(origin); + + // Assert + Assert.True(actual); + } + + [Theory] + [InlineData("http://sub.domain", "http://*.domain")] + [InlineData("http://sub.sub.domain", "http://*.domain")] + [InlineData("http://sub.sub.domain", "http://*.sub.domain")] + [InlineData("http://sub.domain:4567", "http://*.domain:4567")] + public void IsOriginAnAllowedSubdomain_ReturnsTrue_WhenASubdomain(string origin, string allowedOrigin) + { + // Arrange + var policy = new CorsPolicy(); + policy.Origins.Add(allowedOrigin); + + // Act + var isAllowed = policy.IsOriginAnAllowedSubdomain(origin); + + // Assert + Assert.True(isAllowed); + } + + [Theory] + [InlineData("http://domain", "http://*.domain")] + [InlineData("http://sub.domain", "http://domain")] + [InlineData("http://sub.domain:1234", "http://*.domain:5678")] + [InlineData("http://sub.domain", "http://domain.*")] + [InlineData("http://sub.sub.domain", "http://sub.*.domain")] + [InlineData("http://sub.domain.hacker", "http://*.domain")] + [InlineData("https://sub.domain", "http://*.domain")] + public void IsOriginAnAllowedSubdomain_ReturnsFalse_WhenNotASubdomain(string origin, string allowedOrigin) + { + // Arrange + var policy = new CorsPolicy(); + policy.Origins.Add(allowedOrigin); + + // Act + var isAllowed = policy.IsOriginAnAllowedSubdomain(origin); + + // Assert + Assert.False(isAllowed); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyTests.cs b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyTests.cs index 4264164ed0..f49e30fabc 100644 --- a/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyTests.cs +++ b/test/Microsoft.AspNetCore.Cors.Test/CorsPolicyTests.cs @@ -24,6 +24,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.Empty(corsPolicy.Methods); Assert.Empty(corsPolicy.Origins); Assert.Null(corsPolicy.PreflightMaxAge); + Assert.NotNull(corsPolicy.IsOriginAllowed); } [Fact] diff --git a/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs b/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs index 7edfc895fd..73b6e89653 100644 --- a/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs +++ b/test/Microsoft.AspNetCore.Cors.Test/CorsServiceTests.cs @@ -58,6 +58,26 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.False(result.VaryByOrigin); } + [Fact] + public void EvaluatePolicy_IsOriginAllowedReturnsFalse_ReturnsInvalidResult() + { + // Arrange + var corsService = new CorsService(new TestCorsOptions()); + var requestContext = GetHttpContext(origin: "http://example.com"); + var policy = new CorsPolicy() + { + IsOriginAllowed = origin => false + }; + policy.Origins.Add("example.com"); + + // Act + var result = corsService.EvaluatePolicy(requestContext, policy); + + // Assert + Assert.Null(result.AllowedOrigin); + Assert.False(result.VaryByOrigin); + } + [Fact] public void EvaluatePolicy_AllowAnyOrigin_DoesNotSupportCredentials_EmitsWildcardForOrigin() { @@ -407,6 +427,28 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure Assert.Equal("http://example.com", result.AllowedOrigin); } + [Fact] + public void EvaluatePolicy_PreflightRequest_IsOriginAllowedReturnsTrue_ReturnsOrigin() + { + // Arrange + var corsService = new CorsService(new TestCorsOptions()); + var requestContext = GetHttpContext( + method: "OPTIONS", + origin: "http://example.com", + accessControlRequestMethod: "PUT"); + var policy = new CorsPolicy + { + IsOriginAllowed = origin => true + }; + policy.Methods.Add("*"); + + // Act + var result = corsService.EvaluatePolicy(requestContext, policy); + + // Assert + Assert.Equal("http://example.com", result.AllowedOrigin); + } + [Fact] public void EvaluatePolicy_PreflightRequest_SupportsCredentials_AllowCredentialsReturnsTrue() { diff --git a/test/Microsoft.AspNetCore.Cors.Test/UriHelpersTests.cs b/test/Microsoft.AspNetCore.Cors.Test/UriHelpersTests.cs new file mode 100644 index 0000000000..ac04cfc3fd --- /dev/null +++ b/test/Microsoft.AspNetCore.Cors.Test/UriHelpersTests.cs @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Xunit; + +namespace Microsoft.AspNetCore.Cors.Infrastructure +{ + public sealed class UriHelpersTests + { + [Theory] + [MemberData(nameof(IsSubdomainOfTestData))] + public void TestIsSubdomainOf(Uri subdomain, Uri domain) + { + // Act + bool isSubdomain = UriHelpers.IsSubdomainOf(subdomain, domain); + + // Assert + Assert.True(isSubdomain); + } + + [Theory] + [MemberData(nameof(IsNotSubdomainOfTestData))] + public void TestIsSubdomainOf_ReturnsFalse_WhenNotSubdomain(Uri subdomain, Uri domain) + { + // Act + bool isSubdomain = UriHelpers.IsSubdomainOf(subdomain, domain); + + // Assert + Assert.False(isSubdomain); + } + + public static IEnumerable IsSubdomainOfTestData + { + get + { + return new[] + { + new object[] {new Uri("http://sub.domain"), new Uri("http://domain")}, + new object[] {new Uri("https://sub.domain"), new Uri("https://domain")}, + new object[] {new Uri("https://sub.domain:5678"), new Uri("https://domain:5678")}, + new object[] {new Uri("http://sub.sub.domain"), new Uri("http://domain")}, + new object[] {new Uri("http://sub.sub.domain"), new Uri("http://sub.domain")} + }; + } + } + + public static IEnumerable IsNotSubdomainOfTestData + { + get + { + return new[] + { + new object[] {new Uri("http://subdomain"), new Uri("http://domain")}, + new object[] {new Uri("https://sub.domain"), new Uri("http://domain")}, + new object[] {new Uri("https://sub.domain:1234"), new Uri("https://domain:5678")}, + new object[] {new Uri("http://domain.tld"), new Uri("http://domain")}, + new object[] {new Uri("http://sub.domain.tld"), new Uri("http://domain")}, + new object[] {new Uri("/relativeUri", UriKind.Relative), new Uri("http://domain")}, + new object[] {new Uri("http://sub.domain"), new Uri("/relative", UriKind.Relative)} + }; + } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Cors.Test/project.json b/test/Microsoft.AspNetCore.Cors.Test/project.json index 6ad6917f35..0145f53774 100644 --- a/test/Microsoft.AspNetCore.Cors.Test/project.json +++ b/test/Microsoft.AspNetCore.Cors.Test/project.json @@ -1,5 +1,8 @@ { "version": "1.1.0-*", + "buildOptions": { + "keyFile": "../../tools/Key.snk" + }, "dependencies": { "CorsMiddlewareWebSite": "1.0.0-*", "dotnet-test-xunit": "2.2.0-*", diff --git a/test/WebSites/CorsMiddlewareWebSite/project.json b/test/WebSites/CorsMiddlewareWebSite/project.json index f447a14c31..b5cfea5e07 100644 --- a/test/WebSites/CorsMiddlewareWebSite/project.json +++ b/test/WebSites/CorsMiddlewareWebSite/project.json @@ -1,6 +1,7 @@ { "buildOptions": { - "emitEntryPoint": true + "emitEntryPoint": true, + "keyFile": "../../../tools/Key.snk" }, "dependencies": { "Microsoft.AspNetCore.Cors": "1.2.0-*",