Skip to content

Commit 5c1a3d8

Browse files
committed
Update CORS middleware to use endpoint metadata
1 parent 00cf0a4 commit 5c1a3d8

File tree

13 files changed

+1153
-977
lines changed

13 files changed

+1153
-977
lines changed

src/CORS/CORS.sln

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleOrigin", "samples\Sam
2828
EndProject
2929
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0CCC5C1B-F548-4A17-96F8-14C700093FA0}"
3030
ProjectSection(SolutionItems) = preProject
31-
.appveyor.yml = .appveyor.yml
32-
.gitattributes = .gitattributes
3331
.gitignore = .gitignore
34-
.travis.yml = .travis.yml
35-
build.cmd = build.cmd
36-
build.ps1 = build.ps1
37-
build.sh = build.sh
38-
CONTRIBUTING.md = CONTRIBUTING.md
3932
Directory.Build.props = Directory.Build.props
4033
Directory.Build.targets = Directory.Build.targets
41-
LICENSE.txt = LICENSE.txt
42-
NuGet.config = NuGet.config
4334
NuGetPackageVerifier.json = NuGetPackageVerifier.json
4435
README.md = README.md
45-
version.xml = version.xml
4636
EndProjectSection
4737
EndProject
4838
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "test\FunctionalTests\FunctionalTests.csproj", "{99EB6889-C7D8-4BC3-AF99-B966B9E64C81}"

src/CORS/build/dependencies.props

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,21 @@
33
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
44
</PropertyGroup>
55
<PropertyGroup Label="Package Versions">
6-
<InternalAspNetCoreSdkPackageVersion>3.0.0-build-20181116.1</InternalAspNetCoreSdkPackageVersion>
7-
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
8-
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
9-
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.7.0-alpha1-10742</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
10-
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreServerKestrelPackageVersion>
11-
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreStaticFilesPackageVersion>
12-
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-alpha1-10742</MicrosoftAspNetCoreTestHostPackageVersion>
13-
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
14-
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
15-
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
16-
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingConsolePackageVersion>
17-
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsLoggingTestingPackageVersion>
18-
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview-181113-11</MicrosoftExtensionsOptionsPackageVersion>
19-
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview1-26907-05</MicrosoftNETCoreAppPackageVersion>
6+
<InternalAspNetCoreSdkPackageVersion>3.0.0-build-20181120.4</InternalAspNetCoreSdkPackageVersion>
7+
<MicrosoftAspNetCoreHttpExtensionsPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreHttpExtensionsPackageVersion>
8+
<MicrosoftAspNetCoreRoutingPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreRoutingPackageVersion>
9+
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
10+
<MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>0.3.0-preview-18605-0080</MicrosoftAspNetCoreServerIntegrationTestingPackageVersion>
11+
<MicrosoftAspNetCoreServerKestrelPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreServerKestrelPackageVersion>
12+
<MicrosoftAspNetCoreStaticFilesPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreStaticFilesPackageVersion>
13+
<MicrosoftAspNetCoreTestHostPackageVersion>3.0.0-preview-18605-0080</MicrosoftAspNetCoreTestHostPackageVersion>
14+
<MicrosoftExtensionsConfigurationAbstractionsPackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsConfigurationAbstractionsPackageVersion>
15+
<MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion>
16+
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
17+
<MicrosoftExtensionsLoggingConsolePackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsLoggingConsolePackageVersion>
18+
<MicrosoftExtensionsLoggingTestingPackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsLoggingTestingPackageVersion>
19+
<MicrosoftExtensionsOptionsPackageVersion>3.0.0-preview.18572.1</MicrosoftExtensionsOptionsPackageVersion>
20+
<MicrosoftNETCoreAppPackageVersion>3.0.0-preview-27122-01</MicrosoftNETCoreAppPackageVersion>
2021
<MicrosoftNETTestSdkPackageVersion>15.6.1</MicrosoftNETTestSdkPackageVersion>
2122
<MoqPackageVersion>4.10.0</MoqPackageVersion>
2223
<XunitAnalyzersPackageVersion>0.10.0</XunitAnalyzersPackageVersion>

src/CORS/samples/SampleDestination/Program.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.IO;
56
using Microsoft.AspNetCore.Hosting;
67
using Microsoft.Extensions.Logging;
@@ -11,12 +12,30 @@ public class Program
1112
{
1213
public static void Main(string[] args)
1314
{
15+
Type startupType = null;
16+
17+
var startup = Environment.GetEnvironmentVariable("CORS_STARTUP");
18+
switch (startup)
19+
{
20+
case "Startup":
21+
startupType = typeof(Startup);
22+
break;
23+
case "StartupWithoutEndpointRouting":
24+
startupType = typeof(StartupWithoutEndpointRouting);
25+
break;
26+
}
27+
28+
if (startupType == null)
29+
{
30+
throw new InvalidOperationException("Could not resolve the startup type. Unexpected CORS_STARTUP environment variable.");
31+
}
32+
1433
var host = new WebHostBuilder()
1534
.UseKestrel()
1635
.UseUrls("http://+:9000")
1736
.UseContentRoot(Directory.GetCurrentDirectory())
1837
.ConfigureLogging(factory => factory.AddConsole())
19-
.UseStartup<Startup>()
38+
.UseStartup(startupType)
2039
.Build();
2140

2241
host.Run();

src/CORS/samples/SampleDestination/SampleDestination.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.0</TargetFramework>
@@ -11,6 +11,7 @@
1111
<ItemGroup>
1212
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="$(MicrosoftAspNetCoreServerKestrelPackageVersion)" />
1313
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsolePackageVersion)" />
14+
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="$(MicrosoftAspNetCoreRoutingPackageVersion)" />
1415
</ItemGroup>
1516

1617
</Project>

src/CORS/samples/SampleDestination/Startup.cs

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
using System;
54
using System.Net;
6-
using System.Text;
75
using System.Threading.Tasks;
86
using Microsoft.AspNetCore.Builder;
97
using Microsoft.AspNetCore.Hosting;
@@ -16,72 +14,64 @@ namespace SampleDestination
1614
public class Startup
1715
{
1816
private static readonly string DefaultAllowedOrigin = $"http://{Dns.GetHostName()}:9001";
19-
private readonly ILogger<Startup> _logger;
17+
private readonly ILogger<StartupWithoutEndpointRouting> _logger;
2018

2119
public Startup(ILoggerFactory loggerFactory)
2220
{
23-
_logger = loggerFactory.CreateLogger<Startup>();
21+
_logger = loggerFactory.CreateLogger<StartupWithoutEndpointRouting>();
2422
_logger.LogInformation($"Setting up CORS middleware to allow clients on {DefaultAllowedOrigin}");
2523
}
2624

2725
public void ConfigureServices(IServiceCollection services)
2826
{
29-
services.AddCors();
30-
}
31-
32-
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
33-
{
34-
app.Map("/allow-origin", innerBuilder =>
27+
services.AddCors(options =>
3528
{
36-
innerBuilder.UseCors(policy => policy
29+
options.AddPolicy("AllowOrigin", policy => policy
3730
.WithOrigins(DefaultAllowedOrigin)
3831
.AllowAnyMethod()
3932
.AllowAnyHeader());
4033

41-
innerBuilder.UseMiddleware<SampleMiddleware>();
42-
});
43-
44-
app.Map("/allow-header-method", innerBuilder =>
45-
{
46-
innerBuilder.UseCors(policy => policy
34+
options.AddPolicy("AllowHeaderMethod", policy => policy
4735
.WithOrigins(DefaultAllowedOrigin)
4836
.WithHeaders("X-Test", "Content-Type")
4937
.WithMethods("PUT"));
5038

51-
innerBuilder.UseMiddleware<SampleMiddleware>();
52-
});
53-
54-
app.Map("/allow-credentials", innerBuilder =>
55-
{
56-
innerBuilder.UseCors(policy => policy
39+
options.AddPolicy("AllowCredentials", policy => policy
5740
.WithOrigins(DefaultAllowedOrigin)
5841
.AllowAnyHeader()
5942
.WithMethods("GET", "PUT")
6043
.AllowCredentials());
6144

62-
innerBuilder.UseMiddleware<SampleMiddleware>();
63-
});
64-
65-
app.Map("/exposed-header", innerBuilder =>
66-
{
67-
innerBuilder.UseCors(policy => policy
45+
options.AddPolicy("ExposedHeader", policy => policy
6846
.WithOrigins(DefaultAllowedOrigin)
6947
.WithExposedHeaders("X-AllowedHeader", "Content-Length"));
7048

71-
innerBuilder.UseMiddleware<SampleMiddleware>();
72-
});
73-
74-
app.Map("/allow-all", innerBuilder =>
75-
{
76-
innerBuilder.UseCors(policy => policy
49+
options.AddPolicy("AllowAll", policy => policy
7750
.AllowAnyOrigin()
7851
.AllowAnyMethod()
7952
.AllowAnyHeader()
8053
.AllowCredentials());
54+
});
55+
services.AddRouting();
56+
}
8157

82-
innerBuilder.UseMiddleware<SampleMiddleware>();
58+
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
59+
{
60+
var sampleMiddleware = new SampleMiddleware(context => Task.CompletedTask);
61+
62+
app.UseEndpointRouting(routing =>
63+
{
64+
routing.Map("/allow-origin", sampleMiddleware.Invoke).RequireCors("AllowOrigin");
65+
routing.Map("/allow-header-method", sampleMiddleware.Invoke).RequireCors("AllowHeaderMethod");
66+
routing.Map("/allow-credentials", sampleMiddleware.Invoke).RequireCors("AllowCredentials");
67+
routing.Map("/exposed-header", sampleMiddleware.Invoke).RequireCors("ExposedHeader");
68+
routing.Map("/allow-all", sampleMiddleware.Invoke).RequireCors("AllowAll");
8369
});
8470

71+
app.UseCors();
72+
73+
app.UseEndpoint();
74+
8575
app.Run(async (context) =>
8676
{
8777
await context.Response.WriteAsync("Hello World!");
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Net;
5+
using Microsoft.AspNetCore.Builder;
6+
using Microsoft.AspNetCore.Hosting;
7+
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Logging;
10+
11+
namespace SampleDestination
12+
{
13+
public class StartupWithoutEndpointRouting
14+
{
15+
private static readonly string DefaultAllowedOrigin = $"http://{Dns.GetHostName()}:9001";
16+
private readonly ILogger<StartupWithoutEndpointRouting> _logger;
17+
18+
public StartupWithoutEndpointRouting(ILoggerFactory loggerFactory)
19+
{
20+
_logger = loggerFactory.CreateLogger<StartupWithoutEndpointRouting>();
21+
_logger.LogInformation($"Setting up CORS middleware to allow clients on {DefaultAllowedOrigin}");
22+
}
23+
24+
public void ConfigureServices(IServiceCollection services)
25+
{
26+
services.AddCors();
27+
}
28+
29+
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
30+
{
31+
app.Map("/allow-origin", innerBuilder =>
32+
{
33+
innerBuilder.UseCors(policy => policy
34+
.WithOrigins(DefaultAllowedOrigin)
35+
.AllowAnyMethod()
36+
.AllowAnyHeader());
37+
38+
innerBuilder.UseMiddleware<SampleMiddleware>();
39+
});
40+
41+
app.Map("/allow-header-method", innerBuilder =>
42+
{
43+
innerBuilder.UseCors(policy => policy
44+
.WithOrigins(DefaultAllowedOrigin)
45+
.WithHeaders("X-Test", "Content-Type")
46+
.WithMethods("PUT"));
47+
48+
innerBuilder.UseMiddleware<SampleMiddleware>();
49+
});
50+
51+
app.Map("/allow-credentials", innerBuilder =>
52+
{
53+
innerBuilder.UseCors(policy => policy
54+
.WithOrigins(DefaultAllowedOrigin)
55+
.AllowAnyHeader()
56+
.WithMethods("GET", "PUT")
57+
.AllowCredentials());
58+
59+
innerBuilder.UseMiddleware<SampleMiddleware>();
60+
});
61+
62+
app.Map("/exposed-header", innerBuilder =>
63+
{
64+
innerBuilder.UseCors(policy => policy
65+
.WithOrigins(DefaultAllowedOrigin)
66+
.WithExposedHeaders("X-AllowedHeader", "Content-Length"));
67+
68+
innerBuilder.UseMiddleware<SampleMiddleware>();
69+
});
70+
71+
app.Map("/allow-all", innerBuilder =>
72+
{
73+
innerBuilder.UseCors(policy => policy
74+
.AllowAnyOrigin()
75+
.AllowAnyMethod()
76+
.AllowAnyHeader()
77+
.AllowCredentials());
78+
79+
innerBuilder.UseMiddleware<SampleMiddleware>();
80+
});
81+
82+
app.Run(async (context) =>
83+
{
84+
await context.Response.WriteAsync("Hello World!");
85+
});
86+
}
87+
}
88+
}

src/CORS/samples/SampleOrigin/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System.IO;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Cors;
5+
using Microsoft.AspNetCore.Routing;
6+
using System;
7+
using System.Linq;
8+
9+
namespace Microsoft.AspNetCore.Builder
10+
{
11+
public static class CorsEndpointConventionBuilderExtensions
12+
{
13+
public static IEndpointConventionBuilder RequireCors(this IEndpointConventionBuilder builder, string policyName)
14+
{
15+
if (builder == null)
16+
{
17+
throw new ArgumentNullException(nameof(builder));
18+
}
19+
20+
builder.Apply(endpointBuilder =>
21+
{
22+
endpointBuilder.Metadata.Add(new EnableCorsAttribute(policyName));
23+
});
24+
return builder;
25+
}
26+
}
27+
}

src/CORS/src/Microsoft.AspNetCore.Cors/Infrastructure/CorsMiddleware.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using Microsoft.AspNetCore.Cors.Internal;
77
using Microsoft.AspNetCore.Http;
8+
using Microsoft.AspNetCore.Http.Endpoints;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.Extensions.Logging.Abstractions;
1011

@@ -124,7 +125,7 @@ public Task Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider)
124125

125126
private async Task InvokeCore(HttpContext context, ICorsPolicyProvider corsPolicyProvider)
126127
{
127-
var corsPolicy = _policy ?? await corsPolicyProvider.GetPolicyAsync(context, _corsPolicyName);
128+
var corsPolicy = _policy ?? await corsPolicyProvider.GetPolicyAsync(context, ResolveCorsPolicyName(context));
128129
if (corsPolicy == null)
129130
{
130131
Logger?.NoCorsPolicyFound();
@@ -149,6 +150,12 @@ private async Task InvokeCore(HttpContext context, ICorsPolicyProvider corsPolic
149150
}
150151
}
151152

153+
internal string ResolveCorsPolicyName(HttpContext context)
154+
{
155+
var endpoint = context.GetEndpoint();
156+
return endpoint?.Metadata.GetMetadata<IEnableCorsAttribute>()?.PolicyName ?? _corsPolicyName;
157+
}
158+
152159
private static Task OnResponseStarting(object state)
153160
{
154161
var (middleware, context, result) = (Tuple<CorsMiddleware, HttpContext, CorsResult>)state;

src/CORS/src/Microsoft.AspNetCore.Cors/Microsoft.AspNetCore.Cors.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<Description>CORS middleware and policy for ASP.NET Core to enable cross-origin resource sharing.
@@ -13,6 +13,7 @@ Microsoft.AspNetCore.Cors.EnableCorsAttribute</Description>
1313

1414
<ItemGroup>
1515
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="$(MicrosoftAspNetCoreHttpExtensionsPackageVersion)" />
16+
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="$(MicrosoftAspNetCoreRoutingPackageVersion)" />
1617
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="$(MicrosoftExtensionsConfigurationAbstractionsPackageVersion)" />
1718
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(MicrosoftExtensionsDependencyInjectionAbstractionsPackageVersion)" />
1819
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(MicrosoftExtensionsLoggingAbstractionsPackageVersion)" />

0 commit comments

Comments
 (0)