我希望使用以下标准为web-api应用程序启用CORS:
mysite.com
和www.mysite.com
相同我想以优雅的方式为多个网站执行此操作,而不是将所有排列设置为以逗号分隔。
提前致谢!
答案 0 :(得分:4)
除了明确指定所有排列之外,我能想到的唯一方法是实现自定义CORS策略。
您可以详细了解here。
答案 1 :(得分:3)
你走了。
如果需要任何修订或错误修复,请添加Git gist。
public class WildcardOriginCorsPolicy : Attribute, ICorsPolicyProvider
{
private readonly string _origins;
private readonly string _headers;
private readonly string _methods;
//private readonly CorsPolicy _policy;
//
// Summary:
// Initializes a new instance of the WildcardOriginCorsPolicy class.
//
// Parameters:
// origins:
// Comma-separated list of origins that are allowed to access the resource. Use
// "*" to allow all.
// "*.example.com" for subdomains
//
// headers:
// Comma-separated list of headers that are supported by the resource. Use "*" to
// allow all. Use null or empty string to allow none.
//
// methods:
// Comma-separated list of methods that are supported by the resource. Use "*" to
// allow all. Use null or empty string to allow none.
public WildcardOriginCorsPolicy(string origins, string headers, string methods)
{
this._origins = origins;
this._headers = headers;
this._methods = methods;
}
public bool SupportsCredentials { get; set; }
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var policy = CreatePolicy(request.GetCorsRequestContext(), this._origins, this._headers, this._methods);
policy.SupportsCredentials = this.SupportsCredentials;
return Task.FromResult(policy);
}
private static CorsPolicy CreatePolicy(CorsRequestContext requestContext, string origins, string headers, string methods)
{
var corsPolicy = new CorsPolicy();
if (origins == "*")
{
corsPolicy.AllowAnyOrigin = true;
}
else
{
var originsStringArray = origins.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var requestOrigin = requestContext.Origin.ToLowerInvariant();
foreach (var originItem in originsStringArray)
{
////Check if the current request uri matches with any of the wildcard origins.
if (Regex.IsMatch(requestOrigin, WildCardToRegularExpression(originItem)))
{
corsPolicy.Origins.Add(requestOrigin);
}
}
}
if (!String.IsNullOrEmpty(headers))
{
if (headers == "*")
{
corsPolicy.AllowAnyHeader = true;
}
else
{
var headersStringArray = headers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
corsPolicy.Headers.AddAll(headersStringArray);
}
}
if (!String.IsNullOrEmpty(methods))
{
if (methods == "*")
{
corsPolicy.AllowAnyMethod = true;
}
else
{
var methodsStringArray = methods.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
corsPolicy.Methods.AddAll(methodsStringArray);
}
}
return corsPolicy;
}
private static string WildCardToRegularExpression(String value)
{
return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$";
}
}
像这样使用它。
var cors = new WildcardOriginCorsPolicy("*.example.com,http://localhost:*", "*", "POST,PUT,DELETE,GET,OPTIONS") { SupportsCredentials = true };
config.EnableCors(cors);
答案 2 :(得分:2)
您可以在没有通配符的情况下为 * .mydomain.com 实施此动态。您可以参考以下方法(自定义CORS策略提供程序)
public class MyCorsPolicy : Attribute, ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var policy = new CorsPolicy();
var requestUri = request.RequestUri;
var authority = requestUri.Authority.ToLowerInvariant();
if (authority.EndsWith(".mydomain.com") || authority == "mydomain.com")
{
// returns a url with scheme, host and port(if different than 80/443) without any path or querystring
var origin = requestUri.GetComponents(System.UriComponents.SchemeAndServer, System.UriFormat.SafeUnescaped);
policy.Origins.Add(origin);
}
return Task.FromResult(policy);
}
}
[MyCorsPolicy]
public class TestController : ApiController
{
}
正如其他帖子中已经提到的,您可以访问网址https://msdn.microsoft.com/en-us/magazine/dn532203.aspx以获取有关自定义CORS策略提供商的更多信息
答案 3 :(得分:0)
干净的端到端实现
CORSpolicy.cs
using System;
using System.Configuration;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Cors;
using System.Web.Http.Cors;
public class CORSPolicy : Attribute, ICorsPolicyProvider
{
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
CorsPolicy policy = null;
var corsRequestContext = request.GetCorsRequestContext();
var originRequested = corsRequestContext.Origin;
if (IsAValiOriginFrom(originRequested))
{
policy = new CorsPolicy
{
AllowAnyHeader = true,
AllowAnyMethod = true,
};
policy.Origins.Add(originRequested);
}
return Task.FromResult(policy);
}
private bool IsAValiOriginFrom(string origin)
{
var isValid = false;
var corsAllowed = ConfigurationManager.AppSettings["CORSDomains"].Split(',');
foreach (var cor in corsAllowed)
{
if (origin.EndsWith(cor, StringComparison.InvariantCultureIgnoreCase))
{
isValid = true;
break;
}
}
return isValid;
}
}
TestController.cs
using System;
using System.Web.Http;
[CORSPolicy]
[RoutePrefix("api/v1/Test")]
public class TestController : ApiController
{
// GET: api/v1/Test/123
[HttpGet]
[Route("{clientId}")]
public string Get(int clientId)
{
return "123456";
}
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="CORSDomains" value="test.net,example.com" />
</appSettings>
</configuration>