कई डोमेन के साथ एक्सेस-कंट्रोल-अनुमति-मूल


99

अपने 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" />

लेकिन उनमें से कोई भी काम नहीं करता है। सही सिंटैक्स क्या है?

जवाबों:


79

केवल एक 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");
}

2
जो मेरे सवाल का जवाब देता है। मुझे यकीन नहीं है कि क्यों Microsoft web.config में कई मूल निर्दिष्ट करने की अनुमति नहीं देता है ...
सैम

17
मैं इस कोड को कहां जोड़ सकता हूं? मेरे पास सर्वर द्वारा तैयार की गई सादा पाठ फाइलें हैं और AJAX के माध्यम से पढ़ी जाती हैं, कोई कोड नहीं। मैं अपनी निर्देशिका में पाठ फ़ाइलों तक पहुंच को प्रतिबंधित करने के लिए कोड कहां रख सकता हूं?
हैरी

3
@Simon_Weaver एक ऐसा *मूल्य है जो किसी भी उत्पत्ति को संसाधन तक पहुंचने की अनुमति देता है। हालाँकि मूल प्रश्न डोमेन के एक सेट को सफेद करने के बारे में पूछ रहा था।
मोनसुर

2
के रूप में मैं asp के लिए नया हूँ .net मैं पूछ सकता हूँ कि मैं अपने asp .net वेब एपीआई परियोजना में यह कोड कहाँ रख सकता हूँ?
अमृत

93

IIS 7.5+ और रीराइट 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>

सर्वर चर RESPONSE_Access_Control_Allow_Originभाग को समझाते हुए :
पुनर्लेखन में आप बाद में किसी भी स्ट्रिंग का उपयोग कर सकते हैं RESPONSE_और यह हेडर के नाम के रूप में शेष शब्द (इस मामले में प्रवेश-नियंत्रण-अनुमति-उत्पत्ति) का उपयोग करके रिस्पांस हेडर बनाएगा। पुनर्लेखन में डैश के बजाय "_" अंडरस्कोर का उपयोग होता है - "" (फिर से लिखना उन्हें डैश में परिवर्तित करता है)

सर्वर चर को समझाते हुए HTTP_ORIGIN:
इसी तरह, रीराइट में आप HTTP_उपसर्ग के रूप में उपयोग करके किसी भी अनुरोध हेडर को पकड़ सकते हैं । डैश के साथ समान नियम (डैश के बजाय अंडरस्कोर "_" का उपयोग करें) - ")।


क्या आप IIS 7.5 के साथ काम नहीं करने का कोई कारण सोच सकते हैं?
फिल रिकेट्स

मुझे लगता है कि यह काम करना चाहिए। मैंने IIS 8.5 संस्करण निर्दिष्ट किया क्योंकि यह वह जगह है जहां मैंने इसका परीक्षण किया।
पैको ज़ारते

4
@PacoZarate अच्छा लगा, शानदार टिप। रेगेक्स को सरल बनाने के लिए, और इसे अधिक सामान्य बनाने के लिए, आप उपयोग कर सकते हैं - (http(s)?:\/\/((.+\.)?(domain1|domain2)\.(com|org|net)))। इस तरह आप अन्य डोमेन को काफी आसान बना सकते हैं और कई टॉप-लेवल डोमेन (जैसे कॉम, ऑर्ग, नेट आदि) का समर्थन कर सकते हैं।
मर्लिन

4
बस IIS 7.5 में यह कोशिश की। सिर्फ ठीक काम करने लगता है।
पूर्वद्रष्टा

2
कैशिंग से परेशानी? Web.config को ट्विक करने के बाद, पहली वेबसाइट मैं ठीक-ठाक से मेल खाता हूं, लेकिन दूसरा पहले जैसा ही हेडर देता है। इस प्रकार डोमेन बहुत अधिक मेल नहीं खाते हैं।
Airn5475

20

Web.API में इस विशेषता को http://www.asp.net/web-api/overview/security/en enable-cross-origin-requests-in-web-apiMicrosoft.AspNet.WebApi.Cors पर विस्तृत रूप से उपयोग करके जोड़ा जा सकता है

MVC में आप इस कार्य को करने के लिए एक फ़िल्टर विशेषता बना सकते हैं:

[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
}

क्या आप जानते हैं कि .Net / MVC के कौन से संस्करण इसके लिए काम करते हैं?
केबी 42

मैं इसे सफलतापूर्वक .net 4 / MVC 3 में उपयोग कर रहा हूं - जहां तक ​​मुझे पता है कि इसे उच्च संस्करणों में काम करना चाहिए, लेकिन बाद में MVC संस्करणों में वैश्विक फ़िल्टर को पंजीकृत करने का एक पसंदीदा तरीका हो सकता है।
रोब चर्च

कृपया इसके WEB API 2 समाधान पर ध्यान दें। WEB एपीआई 1 के लिए नहीं।
सामिह ए

5

हर उत्तर को पढ़ने और उन्हें आजमाने के बाद, उनमें से किसी ने भी मेरी मदद नहीं की। कहीं और खोजते समय मैंने जो पाया वह यह है कि आप एक कस्टम विशेषता बना सकते हैं जिसे आप अपने नियंत्रक में जोड़ सकते हैं। यह EnableCors वालों को अधिलेखित कर देता है और इसमें श्वेतसूची वाले डोमेन जोड़ देता है।

यह समाधान अच्छी तरह से काम कर रहा है क्योंकि यह आपके नियंत्रक पर 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

मैंने सोचा कि मैं यहाँ किसी को भी जरूरत के लिए छोड़ दूँगा।


यह लिंक-ओनली उत्तर है। कृपया उत्तर को अपने स्थान पर खड़ा करें।
Unslander मोनिका

1
ठीक है, मैं यहां नया हूं, क्या यह अधिक है जैसा कि इसे होना चाहिए?
हेल्फा

3

मैं 'मोनसूर' की सलाह के बाद अनुरोध हैंडलिंग कोड में इसे हल करने में कामयाब रहा।

string origin = WebOperationContext.Current.IncomingRequest.Headers.Get("Origin");

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

उदाहरण के लिए वेबफॉर्म में यह तरीका है। बस उपलब्ध होने पर Request.Headers का उपयोग करें। और, यदि आवश्यक हो, केवल अनुमत डोमेन को फ़िल्टर करने के लिए एक श्वेतसूची का उपयोग करें।
AFract

3
यह web.config फ़ाइल में <add name = "Access-Control-Allow-Origin" मान = "*" /> जोड़ने जैसा ही अच्छा है
यशायाह 4110

3

IIS 7.5+ के लिए आप IIS CORS मॉड्यूल का उपयोग कर सकते हैं: https://www.iis.net/downloads/microsoft/iis-cors-module

आपका web.config कुछ इस तरह होना चाहिए:

<?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>

आप यहाँ विन्यास संदर्भ पा सकते हैं: https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference


अगर यह काम करता है, जैसा कि यह कहता है, काश, आप यह 3 साल पहले पोस्ट करते! वाह!
माइकल

2

थिंकट्रेक्ट आइडेंटिटीमॉडल लाइब्रेरी में देखें - इसमें पूर्ण कोर्स सपोर्ट है:

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

और यह गतिशील रूप से ACA-Origin को आप चाहते हैं उत्सर्जित कर सकता है।


यह एक बहुत उपयोगी पुस्तकालय जैसा लगता है। लिंक के लिए धन्यवाद।
सैम

1

आप इस कोड को अपने asp.net webapi प्रोजेक्ट में जोड़ सकते हैं

फ़ाइल में Global.asax

    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");
    }
}

0

आप 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);
                }
            }
        };

-3

आपको केवल आवश्यकता है:

  • अपने प्रोजेक्ट में Global.asax जोड़ें,
  • हटाना <add name="Access-Control-Allow-Origin" value="*" />अपने web.config से ।
  • बाद में, Application_BeginRequestGlobal.asax की विधि में इसे जोड़ें :

    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();
    }

मुझे उम्मीद है कि यह मदद मिलेगी। मेरे लिए वह काम है।


जब आप क्रेडेंशियल्स की अनुमति देते हैं, तो "...- उत्पत्ति: *" को छोड़कर काम करता है। यदि आपके पास अनुमति-साख सही है, तो आपको एक डोमेन निर्दिष्ट करना होगा (बस नहीं *)। बस यहीं से इस समस्या की जड़ बन जाती है। अन्यथा, आप सिर्फ "... अनुमति-प्रमाणिकता: असत्य" निर्दिष्ट कर सकते हैं और इसके साथ किया जा सकता है।
रिचर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.