asp.net-core - 具有多个来源和多个标头的 .net 核心 cors
问题描述
我有不同的来源,需要通过 cors 策略允许不同的标头。
例如:
1/ - 来源:abc.com - 标题:A、B
2/ - 来源:bcd.com - 标题:A、C
这是我的代码:
services.AddCors(opt =>
{
opt.AddPolicy(
"ABC",
builder =>
{
builder.WithOrigins("abc.com")
.WithHeaders("A", "B");
});
opt.AddPolicy(
"BCD",
builder =>
{
builder.WithOrigins("bcd.com")
.WithHeaders("A", "C");
});
});
并在 Startup.Configure 中:
builder.UseCors("ABC");
builder.UseCors("BCD");
有关原点的一切工作正常,但问题在于标题。标头仅适用于第一个策略。在上面的代码中,标头可以与 Policy ABC 一起使用。我可以按预期发送带有标头 A 或标头 B 的请求,但对于策略 BCD,如果我发送没有标头的请求。它有效,但如果我发送带有标头 A 或 C 的请求,它就不起作用。
如果我将 BCD 移动到 ABC 之上,BCD 标题就可以了。
解决方案
您可以创建一个自定义中间件,该中间件根据请求的来源检查策略。
public class CustomCorsMiddleware
{
private readonly RequestDelegate _next;
private readonly ICorsService _corsService;
private readonly ICorsPolicyProvider _corsPolicyProvider;
private readonly IDictionary<string, string> _policies;
public CustomCorsMiddleware(
RequestDelegate next,
ICorsService corsService,
ICorsPolicyProvider policyProvider,
IDictionary<string, string> policies)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
_corsService = corsService ?? throw new ArgumentNullException(nameof(corsService));
_corsPolicyProvider = policyProvider ?? throw new ArgumentNullException(nameof(policyProvider));
_policies = policies;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers.ContainsKey(CorsConstants.Origin))
{
string policyName;
bool hasPolicy = this._policies.TryGetValue(context.Request.Headers[CorsConstants.Origin], out policyName);
if (!String.IsNullOrEmpty(policyName) && hasPolicy)
{
CorsPolicy corsPolicy = await _corsPolicyProvider.GetPolicyAsync(context, policyName);
if (corsPolicy != null)
{
var corsResult = _corsService.EvaluatePolicy(context, corsPolicy);
_corsService.ApplyResult(corsResult, context.Response);
var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod];
if (string.Equals(
context.Request.Method,
CorsConstants.PreflightHttpMethod,
StringComparison.OrdinalIgnoreCase) &&
!StringValues.IsNullOrEmpty(accessControlRequestMethod))
{
// Since there is a policy which was identified,
// always respond to preflight requests.
context.Response.StatusCode = StatusCodes.Status204NoContent;
return;
}
}
}
}
await _next(context);
}
}
在您的 Startup.cs 中,您必须定义策略并提供中间件的映射。
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(opt => {
opt.AddPolicy(
"ABC",
builder => {
builder.WithOrigins("abc.com")
.WithHeaders("A", "B");
}
);
opt.AddPolicy(
"BCD",
builder => {
builder.WithOrigins("bcd.com")
.WithHeaders("A", "C");
}
);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
IDictionary<string, string> mappings = new Dictionary<string, string>();
mappings["abc.com"] = "ABC";
mappings["bcd.com"] = "BCD";
app.UseMiddleware<CustomCorsMiddleware>(mappings);
}
希望这可以帮助!
推荐阅读
- python - Pandas 列循环的并行处理
- javascript - 如何将对象转换为对象数组
- computational-geometry - 如何使用镶嵌数据计算点到三角形的最短距离
- javascript - 在 Observable 笔记本中,无法使用 npm 库中的函数,可能是因为无法从库的依赖项中导入函数
- javascript - 如何使用javascript追加/添加元素onclick?
- javascript - 将对象映射到另一个对象 javascript
- html - 为什么我的页脚没有停留在页面底部?
- java - spring-webflux 应用启动失败
- python-3.x - 在python中使用类方法的程序
- android - 剪贴板活动的广播接收器