Asp.net 访问控制允许具有多个域的源站

Asp.net 访问控制允许具有多个域的源站,asp.net,iis,cors,web-config,Asp.net,Iis,Cors,Web Config,在我的web.config中,我想为访问控制允许来源指令指定多个域。我不想使用*。我尝试过这种语法: 这个 这个 这个呢 但它们都不起作用。 正确的语法是什么 只能有一个访问控制允许原点响应头,该头只能有一个原点值。因此,为了实现这一点,您需要一些代码: 获取来源请求标头 检查原点值是否为白名单中的值之一 如果有效,则使用该值设置访问控制允许原点标题 我不认为只有通过web.config就可以做到这一点 if (ValidateRequest()) { Response.

在我的web.config中,我想为
访问控制允许来源
指令指定多个域。我不想使用
*
。我尝试过这种语法:


这个


这个


这个呢


但它们都不起作用。
正确的语法是什么

只能有一个
访问控制允许原点
响应头,该头只能有一个原点值。因此,为了实现这一点,您需要一些代码:

  • 获取
    来源
    请求标头
  • 检查原点值是否为白名单中的值之一
  • 如果有效,则使用该值设置
    访问控制允许原点
    标题
  • 我不认为只有通过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");
    }
    

    查看Thinktecture IdentityModel库——它具有完全的CORS支持:

    并且它可以动态发射您想要的ACA源。

    您只需要:

    • 将Global.asax添加到项目中
    • 从web.config中删除
    • 然后,将其添加到Global.asax的
      应用程序\u 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();
      }
      

    我希望这有帮助。这对我来说很有用。

    根据“monsur”的建议,我在请求处理代码中设法解决了这个问题

    string origin=WebOperationContext.Current.IncomingRequest.Headers.Get(“origin”);
    WebOperationContext.Current.OutgoingResponse.Headers.Add(“访问控制允许原点”,原点);
    
    在Web.API中可以使用
    Microsoft.AspNet.WebApi.Cors添加此属性,详细信息请参见

    在MVC中您可以创建一个过滤器属性来完成这项工作:

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
    AllowMultiple=true,继承的=true)]
    公共类EnableCorsAttribute:FilterAttribute,IActionFilter{
    私有常量字符串IncomingOriginHeader=“Origin”;
    private const string OutgoingOriginHeader=“访问控制允许来源”;
    private const string OutgoingMethodsHeader=“访问控制允许方法”;
    private const string OutgoingAgeHeader=“访问控制最大年龄”;
    已执行ActionExecuted(ActionExecutedContext筛选器上下文)的公共无效{
    //无所事事
    }
    ActionExecuting(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))){
    响应.添加标题(OutgoingOrginHeader,originHeader);
    AddHeader(OutgoingMethodsHeader,“获取、发布、选项”);
    回复:AddHeader(OutgoingAgeHeader,“3600”);
    }
    }
    受保护的布尔值是允许的原点(字符串原点){
    //**替换为您自己的逻辑,以检查原始标题
    返回true;
    }
    }
    
    然后为特定操作/控制器启用它:

    [EnableCors]
    公共类安全控制器:控制器{
    //*剪断*
    [使能CORS]
    公共操作结果签名(Guid键、字符串电子邮件、字符串密码){
    
    或者将其添加到Global.asax.cs中的所有控制器

    受保护的无效应用程序\u Start(){
    //*剪掉*任何现有代码
    //寄存器全局过滤器
    GlobalFilters.Filters.Add(新的EnableCorsAttribute());
    RegisterGlobalFilters(GlobalFilters.Filters);
    //*snip*现有代码
    }
    
    对于IIS 7.5+和重写2.0,您可以使用:

    
    
    解释服务器变量
    RESPONSE\u Access\u Control\u Allow\u Origin
    部分:
    在“重写”中,您可以使用
    响应
    之后的任何字符串,它将使用单词的其余部分作为标题名创建响应标题(在本例中,访问控制允许原点)。重写使用下划线“”而不是破折号“-”(重写将其转换为破折号)

    解释服务器变量HTTP_ORIGIN


    类似地,在“重写”中,您可以使用
    HTTP\u
    作为前缀获取任何请求头。破折号的规则相同(使用下划线“\u”而不是破折号“-”).

    在阅读并尝试了所有答案后,没有一个答案对我有帮助。我在其他地方搜索时发现,您可以创建一个自定义属性,然后将其添加到控制器中。它覆盖EnableCors,并在其中添加白名单域

    此解决方案运行良好,因为它允许您在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);
            }
        }
    }
    
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple=false)]
    公共类EnableCorsByAppSettingAttribute:属性,ICorsPolicyProvider
    {
    const string defaultKey=“whiteListDomainCors”;
    私有只读字符串;
    私营企业;
    /// 
    ///默认情况下,使用“cors:AllowedOrigins”AppSetting键
    /// 
    公共启用corsbyappsettingattribute()
    :this(defaultKey)//使用默认的AppSetting键
    {
    }
    /// 
    ///启用交叉原点
    /// 
    ///定义有效来源的AppSetting键
    public EnableCorsByAppSettingAttribute(字符串appSettingKey)
    {
    //收集逗号分隔的源代码
    this.rawrorients=AppSettings.wh
    
    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);
                    }
                }
            };
    
        protected void Application_BeginRequest()
    {
        string origin = Request.Headers.Get("Origin");
        if (Request.HttpMethod == "OPTIONS")
        {
            Response.AddHeader("Access-Control-Allow-Origin", origin);
            Response.AddHeader("Access-Control-Allow-Headers", "*");
            Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
            Response.StatusCode = 200;
            Response.End();
        }
        else
        {
            Response.AddHeader("Access-Control-Allow-Origin", origin);
            Response.AddHeader("Access-Control-Allow-Headers", "*");
            Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");
        }
    }
    
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <cors enabled="true" failUnlistedOrigins="true">
                <add origin="http://localhost:1506">
                    <allowMethods>                    
                        <add method="GET" />
                        <add method="HEAD" />
                        <add method="POST" />
                        <add method="PUT" /> 
                        <add method="DELETE" /> 
                    </allowMethods>
                </add>
                <add origin="http://localhost:1502">
                    <allowMethods>
                        <add method="GET" />
                        <add method="HEAD" />
                        <add method="POST" />
                        <add method="PUT" /> 
                        <add method="DELETE" /> 
                    </allowMethods>
                </add>
            </cors>
        </system.webServer>
    </configuration>