Asp.net Web API中子域的CORS策略定义
我有一个asp.net web api应用程序。此应用程序将xhr请求发送到驻留在另一个web服务器中的web api后端。对于跨域请求问题,我已经为web api启用了CORS选项。它适用于指定的URLAsp.net Web API中子域的CORS策略定义,asp.net,asp.net-web-api,cors,Asp.net,Asp.net Web Api,Cors,我有一个asp.net web api应用程序。此应用程序将xhr请求发送到驻留在另一个web服务器中的web api后端。对于跨域请求问题,我已经为web api启用了CORS选项。它适用于指定的URL [EnableCors(origins: @"http://sub.company.com", headers: "*", methods: "get,post")] 它在sub.company.com上运行,但是,它不适用于我指定的子域的子域,如s1.sub.company.com。我将
[EnableCors(origins: @"http://sub.company.com", headers: "*", methods: "get,post")]
它在sub.company.com上运行,但是,它不适用于我指定的子域的子域,如s1.sub.company.com。我将该子域附加到策略中,但再次无效
[EnableCors(origins: @"http://sub.company.com, http://s1.sub.company.com", headers: "*", methods: "get,post")]
如何解决此问题?您可以创建自定义CORS策略来解决此问题。如果根域相同,则允许跨域访问
/// <summary>
/// Cors policy provider that will allow cross-domain access if the request and the referrer has same root domain.
/// This also support credential headers and cookies.
/// See http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors
/// </summary>
public class IdenticalRootDomainCorsPolicyProvider : ICorsPolicyProvider
{
private readonly string[] exposedHeaders;
/// <summary> Details information when a cross-domain fails. </summary>
public class CorsPolicyErrorDetails
{
/// <summary> The address from where request origins. </summary>
public Uri Referrer { get; set; }
/// <summary> The request URI. </summary>
public Uri Request { get; set; }
/// <summary> Specific message for the error. </summary>
public string Message { get; set; }
}
/// <summary> Occurs when cross-domain access was not accepted. </summary>
public event Action<CorsPolicyErrorDetails> CorsPolicyError;
/// <summary> Initializes a new instance of the <see cref="IdenticalRootDomainCorsPolicyProvider"/> class. </summary>
/// <param name="exposedHeaders"> Provide a list of header names that should be exposed. </param>
public IdenticalRootDomainCorsPolicyProvider(params string[] exposedHeaders)
{
this.exposedHeaders = exposedHeaders;
}
/// <summary> Gets the <see cref="T:System.Web.Cors.CorsPolicy" />. </summary>
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var origin = request.Headers.Where(x => x.Key == "Origin").Select(x => x.Value.FirstOrDefault()).FirstOrDefault();
if (origin == null)
{
CorsPolicyError?.Invoke(new CorsPolicyErrorDetails { Message = "Could not find Origin in headers.", Request = request.RequestUri });
return Task.FromResult((CorsPolicy)null);
}
var referrer = new Uri(origin);
var referrerRootDomain = referrer.GetRootDomain();
var requestRootDomain = request.RequestUri.GetRootDomain();
var policy = new CorsPolicy();
policy.AllowAnyHeader = true;
policy.AllowAnyMethod = true;
policy.SupportsCredentials = true;
if (referrerRootDomain != requestRootDomain)
{
CorsPolicyError?.Invoke(new CorsPolicyErrorDetails { Referrer = referrer, Request = request.RequestUri });
return Task.FromResult(policy);
}
// Standard ports which browser disregards should be handled (80, 443).
if (referrer.Port == 80 || referrer.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase))
policy.Origins.Add($"{referrer.Scheme}://{referrer.DnsSafeHost}");
else
policy.Origins.Add($"{referrer.Scheme}://{referrer.DnsSafeHost}:{referrer.Port}");
// Add custom headers that should be exposed
foreach (var exposedHeader in exposedHeaders)
{
policy.ExposedHeaders.Add(exposedHeader);
}
return Task.FromResult(policy);
}
}
var corsPolicyProvider = new IdenticalRootDomainCorsPolicyProvider();
corsPolicyProvider.CorsPolicyError += CorsPolicyProviderOnCorsPolicyError;
configuration.EnableCors(corsPolicyProvider);