Access-control-allow-origin з кількома доменами

У моєму web.config я хотів би вказати більш ніж один домен для директиви access-control-allow-origin. Я не хочу використовувати *. Я спробував цей синтаксис:


цей


цей


and цей



але жодна з них не працює. Який правильний синтаксис?

78

8 Відповіді

Може бути лише один заголовок відповіді Access-Control-Allow-Origin , і цей заголовок може мати тільки одне значення. Тому для того, щоб це працювало, потрібно мати код, який:

  1. Захоплює заголовок запиту Походження .
  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");
}
67
додано
Де можна додати цей код? У мене є звичайні текстові файли, створені сервером і читаються через AJAX, без коду взагалі. Де я можу поставити код для обмеження доступу до текстових файлів у моєму каталозі?
додано Автор Harry, джерело
Це відповідає на моє запитання. Я не впевнений, чому корпорація Майкрософт не дозволяє вказати численні джерела в web.config, хоча ....
додано Автор Sam, джерело
Добре це є un-intuitive! Чому це не просто "Access-Control-Allow-Origin: Так"?
додано Автор Simon_Weaver, джерело
@Simon_Weaver має значення * , яке дозволяє будь-якому походженням отримати доступ до ресурсу. Однак оригінальне запитання стосувалося того, чи довіряє набір доменів.
додано Автор monsur, джерело

Для IIS 7.5+ і Rewrite 2.0 можна використовувати:


   
     
         
         
     
   
                    
            
                                
                
                    
                    
                        
                    
                    
                           
            
        
 

Пояснюючи змінну сервера RESPONSE_Access_Control_Allow_Origin : У Rewrite можна використовувати будь-який рядок після RESPONSE_ , і він створить заголовок відповіді, використовуючи решту слова як ім'я заголовка (у цьому випадку Access-Control-Allow-Origin). Перезапис використовує підкреслення "_" замість тире "-" (перезапис перетворює їх у тире)

Пояснюючи змінну сервера HTTP_ORIGIN :
Аналогічно, у Rewrite ви можете захопити будь-який Заголовок Запиту, використовуючи HTTP_ як префікс. Те ж правила з тире (використовуйте підкреслення "_" замість тире "-").

59
додано
Просто спробував це в IIS 7.5. Схоже, працює добре.
додано Автор Prescient, джерело
Виникають проблеми з кешуванням? Після налаштування web.config перший веб-сайт, на який я переходжу, відповідає штрафу, але другий повертає той самий заголовок, як і перший. Таким чином, домени не збігаються.
додано Автор Airn5475, джерело
@PacoZarate це не працює для мене, і я вважаю, що це пов'язано з тим, що вам потрібно спочатку налаштувати AllowedServerVariables в інтерфейсі IIS, інакше це не спрацює. У моєму випадку це неможливо, оскільки я розміщуюся на веб-застосунку Azure і не маю доступу до IIS.
додано Автор Chad Richardson, джерело
@ PacoZarate Я спробував це отримав net :: ERR_CONNECTION_RESET повідомлення. Ви можете допомогти? Я використовую Chrome.
додано Автор NKD, джерело
@PacoZarate Я взяв вашу пораду і задав нові питання тут з деталями: -origins "title =" налаштувати перезапис URL з використанням змінної сервера для підтримки декількох джерел "> stackoverflow.com/questions/40182950/…
додано Автор NKD, джерело
Чи можете ви придумати будь-які причини, чому це не працюватиме з IIS 7.5?
додано Автор Phil Ricketts, джерело
@ NKD я б запропонував вам створити нове питання ТА і розмістити відповідну інформацію для її відтворення, в тому числі, якщо ви налаштовуєте https (або просто http) і скільки доменів ви намагаєтеся обробити. Також, будь ласка, включіть відповідні частини web.config, які замінюють фактичні імена доменів. потім розмістіть посилання тут
додано Автор Paco Zarate, джерело
Думаю, це має спрацювати. Я вказав IIS 8.5 версії, тому що це, де я перевірив його.
додано Автор Paco Zarate, джерело
Так, після установки URL Rewrite 2.0, використовуючи код Paco у web.config і додаючи це остаточно спрацювало!
додано Автор graumanoz, джерело
Хто-небудь має приклад того, як буде виглядати підтримка доменів третього рівня? (тобто mycustomdomain.mywebsite.com) - або це вираження буде охоплювати це? Спроба цього з коробки для мене не працювала в цьому випадку.
додано Автор Dave Cole, джерело
Редагування: Схоже, що рішення компанії @PacoZarate працюють найкраще. У відповіді немає зворотних косих рисок перед прямими рисами і не працює на моєму сервері.
додано Автор Dave Cole, джерело
@ Airn5475, вам вдалося вирішити цю проблему? У нас така ж проблема.
додано Автор Christiaan, джерело
@PacoZarate Хороший, великий наконечник. Щоб спростити регулярне вираження і зробити його більш загальним, ви можете використовувати - (http (s)?: ((. + \ T ))) . Таким чином, ви можете додавати інші домени досить легко і підтримувати декілька доменів верхнього рівня (наприклад, com, org, net і т.д.).
додано Автор Merlin, джерело
Я тільки що пробував на IIS10 і працює відмінно!
додано Автор Sergio Gonçalves, джерело
Ця відповідь краща за прийняту для людей, що використовують Rewrite 2.0. Це дуже зручно, щоб зберегти білий список доменів у web.config замість шару програми.
додано Автор 96khz, джерело

In Web.API this attribute can be added using Microsoft.AspNet.WebApi.Cors as detailed at http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

In MVC you could create a filter attribute to do this work for you:

[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
}
15
додано
Тільки зверніть увагу на його рішення WEB API 2. не для WEB API 1.
додано Автор Samih A, джерело
Я використовую це успішно в .net 4/MVC 3 - наскільки мені відомо, він повинен працювати у більш високих версіях, але може бути кращим способом реєстрації глобального фільтра в більш пізніх версіях MVC.
додано Автор Rob Church, джерело
Чи знаєте ви, які версії .Net/MVC це працює?
додано Автор Keab42, джерело

Прочитавши кожну відповідь і пробуючи їх, ніхто з них не допоміг мені. Що я знайшов під час пошуку в іншому місці, це те, що ви можете створити власний атрибут, який потім можна додати до свого контролера. Він перезаписує елементи 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;

    /// 
/// By default uses "cors:AllowedOrigins" AppSetting key ///
 
    public EnableCorsByAppSettingAttribute()
        : this(defaultKey)//Use default AppSetting key
    {
    }

    /// 
/// Enables Cross Origin ///
 
    /// 
AppSetting key that defines valid origins
    public EnableCorsByAppSettingAttribute(string appSettingKey)
    {
       //Collect comma separated origins
        this.rawOrigins = AppSettings.whiteListDomainCors;
        this.BuildCorsPolicy();
    }

    /// 
/// Build Cors policy ///
 
    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 GetCorsPolicyAsync(HttpRequestMessage request,
                                               CancellationToken cancellationToken)
    {
        return Task.FromResult(this.corsPolicy);
    }
}

    internal static class CollectionExtensions
{
    public static void AddCommaSeperatedValues(this ICollection current, string raw)
    {
        if (current == null)
        {
            return;
        }

        var paths = new List(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

Я подумав, що я опускаю це тут для всіх, хто цього потребує.

3
додано
Це відповідь лише на посилання. Будь ласка, зробіть відповідь самостійно.
додано Автор Kuba Ober, джерело
Гаразд, я новий тут, це більше схоже на те, що він повинен бути ??
додано Автор Helpha, джерело

Подивіться на бібліотеку моделі Thinktecture IdentityModel - вона має повну підтримку CORS:

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

І він може динамічно випромінювати ACA-Origin, який ви хочете.

2
додано
Це схоже на дійсно корисну бібліотеку. Дякуємо за посилання.
додано Автор Sam, джерело

Мені вдалося розв'язати це в коді обробки запитів після консультації з 'monsur'.

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

WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", origin);
2
додано
Це так само добре, як додавання у файл web.config
додано Автор Isaiah4110, джерело
Це можна зробити, наприклад, у webform. Просто використовуйте Request.Headers, коли вони є. Якщо необхідно, використовуйте білий список лише для фільтрування дозволених доменів.
додано Автор AFract, джерело

You only need: - add a Global.asax to your project,
- delete from your web.config.
- after add in the Application_BeginRequest method of Global.asax this:

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

Я сподіваюся, що це допоможе. що працює для мене.

2
додано
Додавання "...- Походження: *" працює, за винятком випадків, коли ви дозволяєте облікові дані. Якщо ви маєте дозволу-облікові дані, встановлені як true, тоді вам слід вказати домен (не просто *). Саме тут лежить суть цієї проблеми. В іншому випадку можна просто вказати "... allow-credentials: false" і зробити з нею.
додано Автор Richard, джерело

Ви можете використовувати owin middle ware для визначення політики 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);
                }
            }
        };
0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug