Поделиться через


Справочник по конфигурации модуля IIS CORS

командой IIS

В этой статье представлен обзор модуля IIS CORS и его конфигурация.

Общие сведения о функциональных возможностях

Модуль MICROSOFT IIS CORS — это расширение, которое позволяет веб-сайтам поддерживать протокол CORS (общий доступ к ресурсам независимо от источника).

Модуль IIS CORS предоставляет администраторам веб-серверов и авторам веб-сайтов способ обеспечить поддержку протокола CORS в своих приложениях. С помощью этого модуля разработчики могут перемещать логику CORS из своих приложений и полагаться на веб-сервер. Обработка модулей запросов CORS определяется правилами, определенными в конфигурации. Эти правила CORS можно легко определить или настроить, что упрощает делегирование всей обработки протокола CORS модулю.

Модуль IIS CORS — это компонент CORS на стороне сервера.

Протокол CORS управляет взаимодействием между клиентом и сервером. Обычно веб-браузеры выступают в качестве клиентского компонента CORS, а сервер IIS — сервер CORS на стороне сервера с помощью модуля IIS CORS.

Запрос CORS возникает, когда клиент, поддерживающий протокол, например веб-браузер, отправляет запрос к домену (источнику), который отличается от текущего домена. Этот сценарий называется запросом между источниками. Если CORS не используется, клиент блокирует запросы независимо от источника. При использовании модуля CORS СЛУЖБЫ IIS будут информировать клиентов о том, можно ли выполнить межкорресный запрос на основе конфигурации IIS.

Предварительный запрос CORS

Предварительный запрос CORS используется для определения того, настроен ли сервер для совместного использования запрашиваемого ресурса между источниками. Предварительная проверка CORS использует метод HTTP OPTIONS с заголовками запроса ACCESS-CONTROL-REQUEST-METHOD и ORIGIN . Модуль IIS CORS предназначен для обработки предварительных запросов CORS до того, как другие модули IIS обработают тот же запрос. Запросы OPTIONS всегда являются анонимными, поэтому модуль CORS предоставляет серверам IIS способ правильно реагировать на предварительный запрос, даже если анонимную проверку подлинности необходимо отключить на сервере.

Конфигурация CORS

СЛУЖБА IIS CORS настраивается с помощью сайта или приложения web.config файла и имеет собственный cors раздел конфигурации в .system.webServer

Ниже приведены примеры конфигурации для включения CORS для сайта с именем contentSite. Источник * разрешает все источники узлов; однако те, которые начинаются с http://* , позже исключаются. https://*.microsoft.com Для источника узла ответ CORS настраивается с помощью различных конфигураций CORS в качестве примера.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add origin="*" />
            <add origin="https://*.microsoft.com"
                 allowCredentials="true"
                 maxAge="120"> 
                <allowHeaders allowAllRequestedHeaders="true">
                    <add header="header1" />
                    <add header="header2" />
                </allowHeaders>
                <allowMethods>
                     <add method="DELETE" />
                </allowMethods>
                <exposeHeaders>
                    <add header="header1" />
                    <add header="header2" />
                </exposeHeaders>
            </add>
            <add origin="http://*" allowed="false" />
        </cors>
    </system.webServer>
</configuration>

С помощью модуля IIS CORS вы можете:

  1. Включите и отключите CORS для всего сервера IIS или для определенного сайта IIS, приложения, виртуального каталога, физического каталога или файла (system.webServer/cors).
  2. Настройте все домены узла источника, которые будут приниматься с помощью правила * узла источника.
  3. Настройте список определенных доменов узла источника и разрешите только запрос CORS, который имеет то же значение заголовка исходного запроса, что и один из перечисленных доменов узла источника.
  4. При настройке списка исходного домена, например http://* или https://*.mydomain.com, настройте домены узла wild карта источника.
  5. Настройте список доменов источника, которые должны быть запрещены как запрос CORS.
  6. Настройте значения заголовка ответа CORS с помощью настроенных значений.

Атрибуты элемента cors

Attribute Описание
enabled Дополнительный логический атрибут.
Указывает, включена ли функция CORS.
Значение по умолчанию — false.
failUnlistedOrigins Дополнительный логический атрибут.
Указывает, следует ли задать код состояния ответа CORS с кодом 403, если запрошенный источник не соответствует заданному списку источников или если узел источника настроен для запрета.
Значение по умолчанию — false.

Добавление правила <источника>

Правила источника

Элемент <add><cors> коллекции указывает отдельный источник, добавляемый в список правил источника.

Атрибуты правила источника

Attribute Описание
origin Обязательный строковый атрибут.
Указывает узел источника, на который необходимо навязать правило источника. Чтобы применить это правило ко всем значениям заголовка исходного запроса, можно использовать звездочку (*). Вы также можете использовать звездочку (*) в качестве подстановочного знака для имени дочернего поддомена. Если существует несколько правил источника, они применяются к наиболее конкретному правилу имени узла источника независимо от допустимого значения атрибута.
allowed Дополнительный логический атрибут.
Указывает, следует ли принимать запрос CORS для исходного узла.
Значение по умолчанию — true.
allowCredentials Дополнительный логический атрибут.
Указывает, следует ли задать заголовок ответа Access-Control-Allow-Credentials: true CORS. Этот атрибут следует использовать только для определенного имени узла источника, а не * узла источника для соответствия протоколу CORS.
Значение по умолчанию — false.
maxAge Необязательный целочисленный атрибут. Длительность в секундах.
Задает значение заголовка Access-Control-Max-Age ответа для предварительного запроса CORS. Заголовок ответа Access-Control-Max-Age должен быть задан только для предварительных запросов CORS. Если вы не хотите задавать заголовок Access-Control-Max-Age в ответе CORS, задайте для этого атрибута значение -1.
Значение по умолчанию — -1.

Использование только правила узла источника *

Если существует только правило узла источника *, модуль IIS CORS имеет несколько другое поведение по сравнению с определенным правилом имени узла источника. Если существует только правило узла источника *, модуль IIS CORS выполняет следующие действия:

  1. Для заголовка ответа Access-Control-Allow-Origin задано значение * независимо от значения заголовка origin запроса, отправленного клиентским компонентом CORS.
  2. Варианты: origin заголовок ответа не добавляется, так как IIS CORS не создает значения заголовка ответа Access-Control-Allow-Origin, отличные от *, и нет необходимости использовать значение заголовка ответа Vary: origin .

Дочерние элементы правила узла источника

Элемент Описание
allowHeaders настраивает коллекцию allowHeaders , которая используется для значения заголовка Access-Control-Allow-Headers ответа CORS для узла-источника , указанного в правиле узла источника.
Заголовок Access-Control-Allow-Headers ответа будет задан только для фактических запросов CORS, а не для предварительных запросов.
allowMethods настраивает коллекцию allowMethods , которая используется для значения заголовка Access-Control-Allow-Methods ответа CORS для исходного узла, указанного в правиле узла источника.
Заголовок Access-Control-Allow-Methods ответа будет задан только для предварительных запросов CORS.
exposeHeaders настраивает коллекцию exposeHeaders , которая используется для значения заголовка Access-Control-Expose-Headers ответа CORS для узла-источника , указанного в правиле узла источника.
Заголовок Access-Control-Expose-Headers ответа будет задан только для фактических запросов CORS, а не для предварительных запросов.

Атрибуты элемента allowHeaders

Attribute Описание
allowAllRequestedHeaders Дополнительный логический атрибут. Если это так, модуль IIS примет значение заданного заголовка запроса CORS Access-Control-Request-Headers и установит заголовок ответа Access-Control-Allow-Headers с тем же значением, что означает, что все заданные заголовки разрешены. Если задано значение false, задается заголовок ответа Access-Control-Allow-Headers со значениями заголовков коллекции allowHeaders, что означает, что разрешены только перечисленные заголовки. Значение по умолчанию — false.

Пример кода

C#

using System;
using System.Text;
using Microsoft.Web.Administration;

internal static class Sample {

    private static void Main() {

        using(ServerManager serverManager = new ServerManager()) {
            Configuration config = serverManager.GetWebConfiguration("contentSite");

            ConfigurationSection corsSection = config.GetSection("system.webServer/cors");
            corsSection["enabled"] = true;
            corsSection["failUnlistedOrigins"] = true;

            ConfigurationElementCollection corsCollection = corsSection.GetCollection();

            ConfigurationElement addElement = corsCollection.CreateElement("add");
            addElement["origin"] = @"*";
            corsCollection.Add(addElement);

            ConfigurationElement addElement1 = corsCollection.CreateElement("add");
            addElement1["origin"] = @"https://*.microsoft.com";
            addElement1["allowCredentials"] = true;
            addElement1["maxAge"] = 120;

            ConfigurationElement allowHeadersElement = addElement1.GetChildElement("allowHeaders");
            allowHeadersElement["allowAllRequestedHeaders"] = true;

            ConfigurationElementCollection allowHeadersCollection = allowHeadersElement.GetCollection();

            ConfigurationElement addElement2 = allowHeadersCollection.CreateElement("add");
            addElement2["header"] = @"header1";
            allowHeadersCollection.Add(addElement2);

            ConfigurationElement addElement3 = allowHeadersCollection.CreateElement("add");
            addElement3["header"] = @"header2";
            allowHeadersCollection.Add(addElement3);

            ConfigurationElementCollection allowMethodsCollection = addElement1.GetCollection("allowMethods");

            ConfigurationElement addElement4 = allowMethodsCollection.CreateElement("add");
            addElement4["method"] = @"DELETE";
            allowMethodsCollection.Add(addElement4);

            ConfigurationElementCollection exposeHeadersCollection = addElement1.GetCollection("exposeHeaders");

            ConfigurationElement addElement5 = exposeHeadersCollection.CreateElement("add");
            addElement5["header"] = @"header1";
            exposeHeadersCollection.Add(addElement5);

            ConfigurationElement addElement6 = exposeHeadersCollection.CreateElement("add");
            addElement6["header"] = @"header2";
            exposeHeadersCollection.Add(addElement6);
            corsCollection.Add(addElement1);

            ConfigurationElement addElement7 = corsCollection.CreateElement("add");
            addElement7["origin"] = @"http://*";
            addElement7["allowed"] = false;
            corsCollection.Add(addElement7);

            serverManager.CommitChanges();
        }
    }
}

JavaScript


var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST/contentSite";

var corsSection = adminManager.GetAdminSection("system.webServer/cors", "MACHINE/WEBROOT/APPHOST/contentSite");
corsSection.Properties.Item("enabled").Value = true;
corsSection.Properties.Item("failUnlistedOrigins").Value = true;

var corsCollection = corsSection.Collection;

var addElement = corsCollection.CreateNewElement("add");
addElement.Properties.Item("origin").Value = "*";
corsCollection.AddElement(addElement);


var addElement1 = corsCollection.CreateNewElement("add");
addElement1.Properties.Item("origin").Value = "https://*.microsoft.com";
addElement1.Properties.Item("allowCredentials").Value = true;
addElement1.Properties.Item("maxAge").Value = 120;
var allowHeadersElement = addElement1.ChildElements.Item("allowHeaders");
allowHeadersElement.Properties.Item("allowAllRequestedHeaders").Value = true;

var allowHeadersCollection = allowHeadersElement.Collection;

var addElement2 = allowHeadersCollection.CreateNewElement("add");
addElement2.Properties.Item("header").Value = "header1";
allowHeadersCollection.AddElement(addElement2);


var addElement3 = allowHeadersCollection.CreateNewElement("add");
addElement3.Properties.Item("header").Value = "header2";
allowHeadersCollection.AddElement(addElement3);


var allowMethodsCollection = addElement1.ChildElements.Item("allowMethods").Collection;

var addElement4 = allowMethodsCollection.CreateNewElement("add");
addElement4.Properties.Item("method").Value = "DELETE";
allowMethodsCollection.AddElement(addElement4);


var exposeHeadersCollection = addElement1.ChildElements.Item("exposeHeaders").Collection;

var addElement5 = exposeHeadersCollection.CreateNewElement("add");
addElement5.Properties.Item("header").Value = "header1";
exposeHeadersCollection.AddElement(addElement5);


var addElement6 = exposeHeadersCollection.CreateNewElement("add");
addElement6.Properties.Item("header").Value = "header2";
exposeHeadersCollection.AddElement(addElement6);

corsCollection.AddElement(addElement1);


var addElement7 = corsCollection.CreateNewElement("add");
addElement7.Properties.Item("origin").Value = "http://*";
addElement7.Properties.Item("allowed").Value = false;
corsCollection.AddElement(addElement7);


adminManager.CommitChanges();

Командная строка (AppCmd)

appcmd.exe set config "contentSite" -section:system.webServer/cors /enabled:"True" /failUnlistedOrigins:"True"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='*']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120']"
appcmd.exe set config "contentSite" -section:system.webServer/cors /[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].allowHeaders.allowAllRequestedHeaders:"True"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].allowHeaders.[header='header1']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].allowHeaders.[header='header2']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].allowMethods.[method='DELETE']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].exposeHeaders.[header='header1']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='https://*.microsoft.com',allowCredentials='True',maxAge='120'].exposeHeaders.[header='header2']"

appcmd.exe set config "contentSite" -section:system.webServer/cors /+"[origin='http://*',allowed='False']"

PowerShell

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors" -name "enabled" -value "True"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors" -name "failUnlistedOrigins" -value "True"

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors" -name "." -value @{origin='*'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors" -name "." -value @{origin='https://*.microsoft.com';allowCredentials='True';maxAge=120}
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/allowHeaders" -name "allowAllRequestedHeaders" -value "True"

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/allowHeaders" -name "." -value @{header='header1'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/allowHeaders" -name "." -value @{header='header2'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/allowMethods" -name "." -value @{method='DELETE'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/exposeHeaders" -name "." -value @{header='header1'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors/add[@origin='https://*.microsoft.com']/exposeHeaders" -name "." -value @{header='header2'}

Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/contentSite'  -filter "system.webServer/cors" -name "." -value @{origin='http://*';allowed='False'}