diff --git a/CORS.sln b/CORS.sln index 9f3b2ba560..87e766660f 100644 --- a/CORS.sln +++ b/CORS.sln @@ -1,7 +1,6 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{84FE6872-A610-4CEC-855F-A84CBF1F40FC}" EndProject @@ -20,6 +19,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{53 EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "CorsMiddlewareWebSite", "test\WebSites\CorsMiddlewareWebSite\CorsMiddlewareWebSite.xproj", "{B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{960E0703-A8A5-44DF-AA87-B7C614683B3C}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleDestination", "SampleDestination\SampleDestination.xproj", "{F6675DC1-AA21-453B-89B6-DA425FB9C3A5}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleOrigin", "SampleOrigin\SampleOrigin.xproj", "{99460370-AE5D-4DC9-8DBF-04DF66D6B21D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +43,14 @@ Global {B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B42D4844-FFF8-4EC2-88D1-3AE95234D9EB}.Release|Any CPU.Build.0 = Release|Any CPU + {F6675DC1-AA21-453B-89B6-DA425FB9C3A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6675DC1-AA21-453B-89B6-DA425FB9C3A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6675DC1-AA21-453B-89B6-DA425FB9C3A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6675DC1-AA21-453B-89B6-DA425FB9C3A5}.Release|Any CPU.Build.0 = Release|Any CPU + {99460370-AE5D-4DC9-8DBF-04DF66D6B21D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99460370-AE5D-4DC9-8DBF-04DF66D6B21D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99460370-AE5D-4DC9-8DBF-04DF66D6B21D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99460370-AE5D-4DC9-8DBF-04DF66D6B21D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -47,5 +60,7 @@ Global {F05BE96F-F869-4408-A480-96935B4835EE} = {F32074C7-087C-46CC-A913-422BFD2D6E0A} {538380BF-0D4C-4E30-8F41-E75C4B1C01FA} = {F32074C7-087C-46CC-A913-422BFD2D6E0A} {B42D4844-FFF8-4EC2-88D1-3AE95234D9EB} = {538380BF-0D4C-4E30-8F41-E75C4B1C01FA} + {F6675DC1-AA21-453B-89B6-DA425FB9C3A5} = {960E0703-A8A5-44DF-AA87-B7C614683B3C} + {99460370-AE5D-4DC9-8DBF-04DF66D6B21D} = {960E0703-A8A5-44DF-AA87-B7C614683B3C} EndGlobalSection EndGlobal diff --git a/SampleDestination/Program.cs b/SampleDestination/Program.cs new file mode 100644 index 0000000000..972cde8b8b --- /dev/null +++ b/SampleDestination/Program.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace SampleDestination +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("hosting.json", optional: true) + .Build(); + + var host = new WebHostBuilder() + .UseKestrel() + .UseConfiguration(config) + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/SampleDestination/SampleDestination.xproj b/SampleDestination/SampleDestination.xproj new file mode 100644 index 0000000000..ac33a6f88b --- /dev/null +++ b/SampleDestination/SampleDestination.xproj @@ -0,0 +1,25 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + f6675dc1-aa21-453b-89b6-da425fb9c3a5 + SampleDestination + .\obj + .\bin\ + v4.5.2 + + + + 2.0 + + + + + + + diff --git a/SampleDestination/Startup.cs b/SampleDestination/Startup.cs new file mode 100644 index 0000000000..5ea6b6d284 --- /dev/null +++ b/SampleDestination/Startup.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace SampleDestination +{ + public class Startup + { + // 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.AddCors(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseCors(policy => policy.WithOrigins("http://origin.sample.com:8080").WithMethods("GET")); + app.UseMiddleware(); + } +} +} diff --git a/SampleDestination/StatusMiddleware.cs b/SampleDestination/StatusMiddleware.cs new file mode 100644 index 0000000000..1f47c634ad --- /dev/null +++ b/SampleDestination/StatusMiddleware.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace SampleDestination +{ + public class StatusMiddleware + { + /// + /// Instantiates a new . + /// + /// The next middleware in the pipeline. + public StatusMiddleware(RequestDelegate next) + { + } + + /// + /// Writes the status of the request sent in response. Does not invoke later middleware in the pipeline. + /// + /// The of the current request. + /// A that completes when writing to the response is done. + public Task Invoke(HttpContext context) + { + if (context == null) + { + throw new ArgumentNullException(nameof(context)); + } + + return context.Response.WriteAsync(context.Response.StatusCode.ToString()); + } + + } +} diff --git a/SampleDestination/hosting.json b/SampleDestination/hosting.json new file mode 100644 index 0000000000..804f92d481 --- /dev/null +++ b/SampleDestination/hosting.json @@ -0,0 +1,3 @@ +{ + "server.urls": "http://destination.sample.com:80" +} \ No newline at end of file diff --git a/SampleDestination/project.json b/SampleDestination/project.json new file mode 100644 index 0000000000..6cb1686ef0 --- /dev/null +++ b/SampleDestination/project.json @@ -0,0 +1,50 @@ +{ + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.1.0-*", + "type": "platform" + }, + "Microsoft.AspNetCore.Diagnostics": "1.2.0-*", + "Microsoft.AspNetCore.Server.IISIntegration": "1.2.0-*", + "Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*", + "Microsoft.Extensions.Logging.Console": "1.2.0-*", + "Microsoft.AspNetCore.Cors": "1.2.0-*", + "Microsoft.Extensions.Configuration.FileExtensions": "1.2.0-*", + "Microsoft.Extensions.Configuration.Json": "1.2.0-preview1-*" + }, + + "tools": { + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-*" + }, + + "frameworks": { + "netcoreapp1.0": { + "imports": [ + "dotnet5.6", + "portable-net45+win8" + ] + } + }, + + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true + }, + + "runtimeOptions": { + "configProperties": { + "System.GC.Server": true + } + }, + + "publishOptions": { + "include": [ + "wwwroot", + "web.config" + ] + }, + + "scripts": { + "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] + } +} diff --git a/SampleDestination/web.config b/SampleDestination/web.config new file mode 100644 index 0000000000..dc0514fca5 --- /dev/null +++ b/SampleDestination/web.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/SampleOrigin/Program.cs b/SampleOrigin/Program.cs new file mode 100644 index 0000000000..68ec70a0b2 --- /dev/null +++ b/SampleOrigin/Program.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; + +namespace SampleOrigin +{ + public class Program + { + public static void Main(string[] args) + { + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("hosting.json", optional: true) + .Build(); + + var host = new WebHostBuilder() + .UseKestrel() + .UseConfiguration(config) + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } + +} diff --git a/SampleOrigin/SampleOrigin.xproj b/SampleOrigin/SampleOrigin.xproj new file mode 100644 index 0000000000..2241431ad0 --- /dev/null +++ b/SampleOrigin/SampleOrigin.xproj @@ -0,0 +1,25 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 99460370-ae5d-4dc9-8dbf-04df66d6b21d + SampleOrigin + .\obj + .\bin\ + v4.5.2 + + + + 2.0 + + + + + + + diff --git a/SampleOrigin/Startup.cs b/SampleOrigin/Startup.cs new file mode 100644 index 0000000000..68a679aec2 --- /dev/null +++ b/SampleOrigin/Startup.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System.IO; + +namespace SampleOrigin +{ + public class Startup + { + // 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) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + loggerFactory.AddConsole(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseDefaultFiles(); + app.UseStaticFiles(); + } + } +} diff --git a/SampleOrigin/hosting.json b/SampleOrigin/hosting.json new file mode 100644 index 0000000000..7d79e9d594 --- /dev/null +++ b/SampleOrigin/hosting.json @@ -0,0 +1,3 @@ +{ + "server.urls": "http://origin.sample.com:8080" +} \ No newline at end of file diff --git a/SampleOrigin/project.json b/SampleOrigin/project.json new file mode 100644 index 0000000000..130536ee70 --- /dev/null +++ b/SampleOrigin/project.json @@ -0,0 +1,50 @@ +{ + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.1.0-*", + "type": "platform" + }, + "Microsoft.AspNetCore.Diagnostics": "1.2.0-*", + "Microsoft.AspNetCore.Server.IISIntegration": "1.2.0-*", + "Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*", + "Microsoft.Extensions.Logging.Console": "1.2.0-*", + "Microsoft.AspNetCore.StaticFiles": "1.2.0-*", + "Microsoft.Extensions.Configuration.FileExtensions": "1.2.0-*", + "Microsoft.Extensions.Configuration.Json": "1.2.0-*" + }, + + "tools": { + "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-*" + }, + + "frameworks": { + "netcoreapp1.0": { + "imports": [ + "dotnet5.6", + "portable-net45+win8" + ] + } + }, + + "buildOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true + }, + + "runtimeOptions": { + "configProperties": { + "System.GC.Server": true + } + }, + + "publishOptions": { + "include": [ + "wwwroot", + "web.config" + ] + }, + + "scripts": { + "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] + } +} diff --git a/SampleOrigin/web.config b/SampleOrigin/web.config new file mode 100644 index 0000000000..dc0514fca5 --- /dev/null +++ b/SampleOrigin/web.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/SampleOrigin/wwwroot/Index.html b/SampleOrigin/wwwroot/Index.html new file mode 100644 index 0000000000..3bc55efdbe --- /dev/null +++ b/SampleOrigin/wwwroot/Index.html @@ -0,0 +1,49 @@ + + + + + + + + +
+ +
+
+ +
+ + \ 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 87343b2f9f..b52e000fa8 100644 --- a/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs +++ b/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsService.cs @@ -83,8 +83,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure if (string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase) && !StringValues.IsNullOrEmpty(accessControlRequestMethod)) { - EvaluatePreflightRequest(context, policy, corsResult); _logger?.IsPreflightRequest(); + EvaluatePreflightRequest(context, policy, corsResult); } else { @@ -105,6 +105,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure _logger?.RequestHasOriginHeader(); AddOriginToResult(origin, policy, result); result.SupportsCredentials = policy.SupportsCredentials; + _logger?.PolicySuccess(); AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders); } @@ -141,7 +142,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure if (!found) { - return; + _logger?.PolicyFailure($"Request method {accessControlRequestMethod} not allowed in CORS policy."); + return; } } @@ -150,6 +152,7 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure !requestHeaders.All(header => CorsConstants.SimpleRequestHeaders.Contains(header, StringComparer.OrdinalIgnoreCase) || policy.Headers.Contains(header, StringComparer.OrdinalIgnoreCase))) { + _logger?.PolicyFailure($"One or more request header(s) not allowed in CORS policy."); return; } @@ -157,7 +160,8 @@ namespace Microsoft.AspNetCore.Cors.Infrastructure result.SupportsCredentials = policy.SupportsCredentials; result.PreflightMaxAge = policy.PreflightMaxAge; result.AllowedMethods.Add(accessControlRequestMethod); - AddHeaderValues(result.AllowedHeaders, requestHeaders); + _logger?.PolicySuccess(); + AddHeaderValues(result.AllowedHeaders, requestHeaders); } /// diff --git a/src/Microsoft.AspNetCore.Cors/Internal/CORSLoggerExtensions.cs b/src/Microsoft.AspNetCore.Cors/Internal/CORSLoggerExtensions.cs index 7672797458..dc63aaf2ae 100644 --- a/src/Microsoft.AspNetCore.Cors/Internal/CORSLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.Cors/Internal/CORSLoggerExtensions.cs @@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Cors.Internal _policyFailure = LoggerMessage.Define( LogLevel.Information, 3, - "Policy execution failed. '{FailureReason}'"); + "Policy execution failed. {FailureReason}"); } public static void IsPreflightRequest(this ILogger logger) @@ -46,10 +46,11 @@ namespace Microsoft.AspNetCore.Cors.Internal _requestHasOriginHeader(logger, null); } - public static void PolicySuccess(this ILogger logger, string failureReason) + public static void PolicySuccess(this ILogger logger) { _policySuccess(logger, null); } + public static void PolicyFailure(this ILogger logger, string failureReason) { _policyFailure(logger, failureReason, null); diff --git a/src/Microsoft.AspNetCore.Cors/project.json b/src/Microsoft.AspNetCore.Cors/project.json index fae16fb6a1..c707dd94a2 100644 --- a/src/Microsoft.AspNetCore.Cors/project.json +++ b/src/Microsoft.AspNetCore.Cors/project.json @@ -23,6 +23,7 @@ "Microsoft.AspNetCore.Http.Extensions": "1.2.0-*", "Microsoft.Extensions.Configuration.Abstractions": "1.2.0-*", "Microsoft.Extensions.DependencyInjection.Abstractions": "1.2.0-*", + "Microsoft.Extensions.Logging.Abstractions": "1.2.0-*", "Microsoft.Extensions.Options": "1.2.0-*", "NETStandard.Library": "1.6.1-*" },