具有多个域的访问控制允许来源

在我的web.config中,我想为access-control-allow-origin指令指定多个域。 我不想使用*。 我试过这个语法:

<add name="Access-Control-Allow-Origin" value="http://localhost:1506, http://localhost:1502" /> 

这个

 <add name="Access-Control-Allow-Origin" value="http://localhost:1506 http://localhost:1502" /> 

这个

 <add name="Access-Control-Allow-Origin" value="http://localhost:1506; http://localhost:1502" /> 

和这个

 <add name="Access-Control-Allow-Origin" value="http://localhost:1506" /> <add name="Access-Control-Allow-Origin" value="http://localhost:1502" /> 

但他们都没有工作。 什么是正确的语法?

只能有一个Access-Control-Allow-Origin响应头,并且该头只能有一个原始值。 因此,为了得到这个工作,你需要有一些代码:

  1. 抓取Origin请求标头。
  2. 检查原始值是否是白名单中的一个值。
  3. 如果有效,则使用该值设置Access-Control-Allow-Origin标题。

我不认为有任何方式完全通过web.config。

 if (ValidateRequest()) { Response.Headers.Remove("Access-Control-Allow-Origin"); Response.AddHeader("Access-Control-Allow-Origin", Request.UrlReferrer.GetLeftPart(UriPartial.Authority)); Response.Headers.Remove("Access-Control-Allow-Credentials"); Response.AddHeader("Access-Control-Allow-Credentials", "true"); Response.Headers.Remove("Access-Control-Allow-Methods"); Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); } 

对于IIS 7.5+和Rewrite 2.0,您可以使用:

 <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" /> </customHeaders> </httpProtocol> <rewrite> <outboundRules> <clear /> <rule name="AddCrossDomainHeader"> <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" /> <conditions logicalGrouping="MatchAll" trackAllCaptures="true"> <add input="{HTTP_ORIGIN}" pattern="(http(s)?://((.+\.)?domain1\.com|(.+\.)?domain2\.com|(.+\.)?domain3\.com))" /> </conditions> <action type="Rewrite" value="{C:0}" /> </rule> </outboundRules> </rewrite> </system.webServer> 

解释服务器variablesRESPONSE_Access_Control_Allow_Origin部分:
在Rewrite中,你可以在RESPONSE_之后使用任何string,并且会使用其余的字作为头名称(在本例中是Access-Control-Allow-Origin)来创buildResponse Header。 重写使用下划线“_”而不是破折号“ – ”(重写将它们转换为破折号)

解释服务器variablesHTTP_ORIGIN
同样,在重写中,您可以使用HTTP_作为前缀获取任何请求头。 与破折号相同的规则(使用下划线“_”而不是破折号“ – ”)。

在Web.API中,可以使用Microsoft.AspNet.WebApi.Cors添加此属性,详情请参见http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web- API

在MVC中,你可以创build一个过滤属性来为你做这个工作:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class EnableCorsAttribute : FilterAttribute, IActionFilter { private const string IncomingOriginHeader = "Origin"; private const string OutgoingOriginHeader = "Access-Control-Allow-Origin"; private const string OutgoingMethodsHeader = "Access-Control-Allow-Methods"; private const string OutgoingAgeHeader = "Access-Control-Max-Age"; public void OnActionExecuted(ActionExecutedContext filterContext) { // Do nothing } public void OnActionExecuting(ActionExecutingContext filterContext) { var isLocal = filterContext.HttpContext.Request.IsLocal; var originHeader = filterContext.HttpContext.Request.Headers.Get(IncomingOriginHeader); var response = filterContext.HttpContext.Response; if (!String.IsNullOrWhiteSpace(originHeader) && (isLocal || IsAllowedOrigin(originHeader))) { response.AddHeader(OutgoingOriginHeader, originHeader); response.AddHeader(OutgoingMethodsHeader, "GET,POST,OPTIONS"); response.AddHeader(OutgoingAgeHeader, "3600"); } } protected bool IsAllowedOrigin(string origin) { // ** replace with your own logic to check the origin header return true; } } 

然后为特定的动作/控制器启用它:

 [EnableCors] public class SecurityController : Controller { // *snip* [EnableCors] public ActionResult SignIn(Guid key, string email, string password) { 

或者将其添加到Global.asax.cs中的所有控制器

 protected void Application_Start() { // *Snip* any existing code // Register global filter GlobalFilters.Filters.Add(new EnableCorsAttribute()); RegisterGlobalFilters(GlobalFilters.Filters); // *snip* existing code } 

查看Thinktecture IdentityModel库 – 它具有完整的CORS支持:

http://brockallen.com/2012/06/28/cors-support-in-webapi-mvc-and-iis-with-thinktecture-identitymodel/

它可以dynamic地发出你想要的ACA-Origin。

我设法通过“monsur”的build议,在Request处理代码中解决这个问题。

 string origin = WebOperationContext.Current.IncomingRequest.Headers.Get("Origin"); WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", origin); 

读完每一个答案并尝试之后,他们都没有帮助我。 我在别处search时发现的是,您可以创build一个自定义属性,然后添加到您的控制器。 它将覆盖EnableCors并在其中添加列入白名单的域。

此解决scheme运行良好,因为它使您可以在webconfig(appsettings)中拥有列入白名单的域,而不是在控制器的EnableCors属性中对它们进行编码。

  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class EnableCorsByAppSettingAttribute : Attribute, ICorsPolicyProvider { const string defaultKey = "whiteListDomainCors"; private readonly string rawOrigins; private CorsPolicy corsPolicy; /// <summary> /// By default uses "cors:AllowedOrigins" AppSetting key /// </summary> public EnableCorsByAppSettingAttribute() : this(defaultKey) // Use default AppSetting key { } /// <summary> /// Enables Cross Origin /// </summary> /// <param name="appSettingKey">AppSetting key that defines valid origins</param> public EnableCorsByAppSettingAttribute(string appSettingKey) { // Collect comma separated origins this.rawOrigins = AppSettings.whiteListDomainCors; this.BuildCorsPolicy(); } /// <summary> /// Build Cors policy /// </summary> private void BuildCorsPolicy() { bool allowAnyHeader = String.IsNullOrEmpty(this.Headers) || this.Headers == "*"; bool allowAnyMethod = String.IsNullOrEmpty(this.Methods) || this.Methods == "*"; this.corsPolicy = new CorsPolicy { AllowAnyHeader = allowAnyHeader, AllowAnyMethod = allowAnyMethod, }; // Add origins from app setting value this.corsPolicy.Origins.AddCommaSeperatedValues(this.rawOrigins); this.corsPolicy.Headers.AddCommaSeperatedValues(this.Headers); this.corsPolicy.Methods.AddCommaSeperatedValues(this.Methods); } public string Headers { get; set; } public string Methods { get; set; } public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return Task.FromResult(this.corsPolicy); } } internal static class CollectionExtensions { public static void AddCommaSeperatedValues(this ICollection<string> current, string raw) { if (current == null) { return; } var paths = new List<string>(AppSettings.whiteListDomainCors.Split(new char[] { ',' })); foreach (var value in paths) { current.Add(value); } } } 

我在网上发现了这个指南,它像一个魅力:

http://jnye.co/Posts/2032/dynamic-cors-origins-from-appsettings-using-web-api-2-2-cross-origin-support

我想我会把这个放在需要帮助的人身上。

您可以使用owin中间件定义cors策略,您可以在其中定义多个cors源

 return new CorsOptions { PolicyProvider = new CorsPolicyProvider { PolicyResolver = context => { var policy = new CorsPolicy() { AllowAnyOrigin = false, AllowAnyMethod = true, AllowAnyHeader = true, SupportsCredentials = true }; policy.Origins.Add("http://foo.com"); policy.Origins.Add("http://bar.com"); return Task.FromResult(policy); } } }; 

你只需要: – 为你的项目添加一个Global.asax,
– 从你的web.config中删除。
– 添加Global.asax的Application_BeginRequest方法后:

 HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin","*"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept"); HttpContext.Current.Response.End(); } 

我希望这个帮助。 为我工作。