具有多个域的访问控制允许来源
在我的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
响应头,并且该头只能有一个原始值。 因此,为了得到这个工作,你需要有一些代码:
- 抓取
Origin
请求标头。 - 检查原始值是否是白名单中的一个值。
- 如果有效,则使用该值设置
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); } } }
我在网上发现了这个指南,它像一个魅力:
我想我会把这个放在需要帮助的人身上。
您可以使用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(); }
我希望这个帮助。 为我工作。
- 将IIS Express绑定到IP地址
- 如何使用c#将JQgrid数据导出到Excel?
- 有条件地隐藏GridView中的CommandField或ButtonField
- 从完整文件path获取文件夹名称 – C#,ASP.NET
- 值/文本更改服务器端后,从文本框中获取文本/值
- Server.MapPath(“。”),Server.MapPath(“〜”),Server.MapPath(@“\”),Server.MapPath(“/”)。 有什么不同?
- 如何使用msbuild发布Web?
- 如何使用int ID列更改ASP.net Identity 2.0的表名?
- 调用@ Html.Partial来显示属于不同控制器的局部视图