.NET Core 端点 + 全局 CORS
Posted
技术标签:
【中文标题】.NET Core 端点 + 全局 CORS【英文标题】:.NET Core Endpoint + Global CORS 【发布时间】:2020-10-21 14:05:04 【问题描述】:我在 official documentation 找到了这个 -
我们建议不要合并策略。使用 [EnableCors] 属性或中间件,不能同时在同一个应用中。
我的场景非常简单——我想全局启用 CORS,但只为一个特定的控制器端点禁用它(端点用于前端小部件,它可以嵌入任何站点,所以我不能在该端点上使用 CORS)。
我不明白他们为什么不建议将这两种方法结合起来——他们不仅不推荐,而且根本行不通。
这是 CORS 的设置:
services.AddCors(opts =>
opts.AddPolicy(nameof(MyCorsPolicy), new MyCorsPolicy());
);
这是Configure
启动方法中的注册
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env)
app.UseRouting();
app.UseCors(nameof(MyCorsPolicy));
app.UseHsts();
app.UseExceptionHandler(env);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => endpoints.MapControllers());
现在在我的 XY 控制器方法中,我的 [DisableCors]
属性不起作用。
任何帮助将不胜感激。谢谢。
【问题讨论】:
【参考方案1】:经过数百次测试和内部 .NET Core 调试,我实现这一点的唯一方法是使用全局 CORS:
services.AddCors(opts =>
opts.AddPolicy(nameof(MyCorsPolicy), new MyCorsPolicy());
);
然后我会创建另一个策略
public class AllowAnyCorsPolicy : CorsPolicy
public AllowAnyCorsPolicy()
Origins.Clear();
IsOriginAllowed = origin => true;
Headers.Clear();
Headers.Add("*");
Methods.Clear();
Methods.Add("*");
SupportsCredentials = true;
并将该策略应用于特定的控制器方法,例如
[EnableCors(nameof(AllowAnyCorsPolicy))]
[HttpPost("/user/add")]
[AllowAnonymous]
public async Task<IActionResult> AddUser(UserRequestModel requestModel)
// ...
如果我使用[DisableCors]
甚至使用默认策略注册,然后将纯[EnableCors]
属性添加到控制器方法,它就行不通了。他们的实现方式很奇怪,因为我认为这可以简化很多,而且我不知道它将来会如何表现,所以我们甚至可以考虑编写我们自己的完整 CORS 中间件。
【讨论】:
【参考方案2】:方式 1。由于尚未配置默认策略,因此 app.UseCors() 单独不会启用 CORS。使用RequireCors
启用所有控制器。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllers()
.RequireCors(MyCorsPolicy);//Enable Cors with endpoint routing
// /xy/getvalues2 and Razor Pages not allow cross-origin requests because no default policy was specified.
endpoints.MapGet("/xy/getvalues2",
context => context.Response.WriteAsync("xy/getvalues2")); //do XY Controller Action logic
endpoints.MapRazorPages();
);
方式 2。[DisableCors]
属性不会禁用已由端点路由启用的 CORS。使用 [EnableCors("MyCorsPolicy")]
为每个控制器启用“MyCorsPolicy
”CORS 策略。为 GetValues2 方法禁用 CORS
。
[EnableCors("MyCorsPolicy")]
[Route("api/[controller]")]
[ApiController]
public class XYController : ControllerBase
// GET api/values
[HttpGet]
public IActionResult Get() =>
ControllerContext.MyDisplayRouteInfo();
// GET: api/values/GetValues2
[DisableCors]
[HttpGet("action")]
public IActionResult GetValues2() =>
ControllerContext.MyDisplayRouteInfo();
【讨论】:
但这意味着如果我想使用这种方法,我需要将[EnableCors("MyCorsPolicy")]
添加到每个控制器,对吧?
没错。 [DisableCors] 属性不会禁用已由终结点路由启用的 CORS。或者您可以使用第一种方法禁用 Cors。以上是关于.NET Core 端点 + 全局 CORS的主要内容,如果未能解决你的问题,请参考以下文章
使用针对 signalR 端点的不同策略覆盖全局 CORS 策略
在 ASP.Net 5 / Core 中启用跨域资源共享 (CORS)