IIS CORS 모듈 구성 참조
IIS 팀에 의해
이 문서에서는 IIS CORS 모듈의 개요를 제공하고 모듈의 구성을 설명합니다.
기능 개요
Microsoft IIS CORS 모듈은 웹 사이트에서 CORS(원본 간 리소스 공유) 프로토콜을 지원할 수 있도록 하는 확장입니다.
IIS CORS 모듈은 웹 서버 관리자 및 웹 사이트 작성자가 애플리케이션이 CORS 프로토콜을 지원하도록 하는 방법을 제공합니다. 이 모듈을 사용하면 개발자는 애플리케이션에서 CORS 논리를 이동하고 웹 서버에 의존할 수 있습니다. 모듈의 CORS 요청 처리는 구성에 정의된 규칙에 따라 결정됩니다. 이러한 CORS 규칙은 쉽게 정의하거나 구성할 수 있으므로 모든 CORS 프로토콜 처리를 모듈에 간단하게 위임할 수 있습니다.
IIS CORS 모듈은 서버 쪽 CORS 구성 요소입니다.
CORS 프로토콜은 클라이언트/서버 통신을 제어합니다. 일반적으로 웹 브라우저는 클라이언트 쪽 CORS 구성 요소 역할을 하지만 IIS 서버는 IIS CORS 모듈의 도움을 받아 서버 쪽 CORS 구성 요소로 작동합니다.
CORS 요청은 웹 브라우저와 같은 프로토콜 인식 클라이언트가 현재 도메인과 다른 도메인(원본)에 요청할 때 발생합니다. 이 시나리오를 원본 간 요청이라고 합니다. CORS를 사용하지 않으면 클라이언트에서 원본 간 요청이 차단됩니다. CORS 모듈을 사용하는 경우 IIS는 IIS 구성에 따라 원본 간 요청을 수행할 수 있는지 여부를 클라이언트에 알릴 것입니다.
CORS 실행 전 요청
CORS 실행 전 요청은 요청되는 리소스가 서버에서 원본 간에 공유되도록 설정되었는지 여부를 결정하는 데 사용됩니다. CORS 사전 실행에서는 ACCESS-CONTROL-REQUEST-METHOD 및 ORIGIN 요청 헤더와 함께 HTTP OPTIONS 메서드를 사용합니다. IIS CORS 모듈은 다른 IIS 모듈이 동일한 요청을 처리하기 전에 CORS 실행 전 요청을 처리하도록 설계되었습니다. OPTIONS 요청은 항상 익명이므로 CORS 모듈은 서버에서 익명 인증을 사용하지 않도록 설정해야 하는 경우에도 실행 전 요청에 올바르게 응답할 수 있는 방법을 IIS 서버에 제공합니다.
CORS 구성
IIS CORS는 사이트 또는 애플리케이션 web.config 파일을 통해 구성되며 내에 자체 cors
구성 섹션이 있습니다 system.webServer
.
다음은 contentSite라는 사이트에 대해 CORS를 사용하도록 설정하는 구성 예제입니다. * 원본은 모든 호스트 원본을 허용합니다. 그러나 로 시작하는 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 모듈을 사용하여 다음을 수행할 수 있습니다.
- 전체 IIS 서버 또는 특정 IIS 사이트, 애플리케이션, 가상 디렉터리, 물리적 디렉터리 또는 파일(system.webServer/cors)에 대해 CORS를 사용하거나 사용하지 않도록 설정합니다.
- * 원본 호스트 규칙에 동의하도록 모든 원본 호스트 도메인을 구성합니다.
- 특정 원본 호스트 도메인 목록을 구성하고 원본 요청 헤더 값이 나열된 원본 호스트 도메인 중 하나와 동일한 CORS 요청만 허용합니다.
- 또는
https://*.mydomain.com
와 같은http://*
원본 도메인 목록을 구성할 때 야생 카드 원본 호스트 도메인을 구성합니다. - CORS 요청으로 허용되지 않아야 하는 원본 도메인 목록을 구성합니다.
- 구성된 값으로 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 |
선택적 정수 특성입니다. 기간(초)입니다. 실행 전 CORS 요청에 대한 응답 헤더의 Access-Control-Max-Age 값을 지정합니다. Access-Control-Max-Age 응답 헤더는 CORS 실행 전 요청에 대해서만 설정되어야 합니다. CORS 응답에서 Access-Control-Max-Age 헤더를 설정하지 않으려면 이 특성에 대해 -1을 설정합니다.기본값은 -1 입니다. |
* 원본 호스트 규칙만 사용
* 원본 호스트 규칙만 있는 경우 IIS CORS 모듈에는 특정 원본 호스트 이름 규칙이 있는 경우와 비교하여 몇 가지 다른 동작이 있습니다. * 원본 호스트 규칙만 있는 경우 IIS CORS 모듈은 다음을 수행합니다.
- Access-Control-Allow-Origin 응답 헤더의 값은 클라이언트 쪽 CORS 구성 요소에서 보낸 요청 헤더의
origin
값에 관계없이 *로 설정됩니다. - Vary:
origin
IIS CORS가 * 이외의 Access-Control-Allow-Origin 응답 헤더 값을 생성하지 않으며 Vary:origin
response 헤더 값을 사용할 필요가 없으므로 응답 헤더가 추가되지 않습니다.
원본 호스트 규칙의 자식 요소
요소 | 설명 |
---|---|
allowHeaders | 는 원본 호스트 규칙에 지정된 원본 호스트의 Access-Control-Allow-Headers CORS 응답 헤더 값에 사용되는 allowHeaders 컬렉션을 구성합니다.응답 헤더는 Access-Control-Allow-Headers 실행 전 요청이 아닌 실제 CORS 요청에 대해서만 설정됩니다. |
allowMethods | 는 원본 호스트 규칙에 지정된 원본 호스트의 Access-Control-Allow-Methods CORS 응답 헤더 값에 사용되는 allowMethods 컬렉션을 구성합니다.응답 헤더는 Access-Control-Allow-Methods CORS 실행 전 요청에 대해서만 설정됩니다. |
exposeHeaders | 는 원본 호스트 규칙에 지정된 원본 호스트의 Access-Control-Expose-Headers CORS 응답 헤더 값에 사용되는 exposeHeaders 컬렉션을 구성합니다.응답 헤더는 Access-Control-Expose-Headers 실행 전 요청이 아닌 실제 CORS 요청에 대해서만 설정됩니다. |
allowHeaders 요소의 특성
Attribute | 설명 |
---|---|
allowAllRequestedHeaders |
선택적 부울 특성입니다. 이 경우 IIS 모듈은 지정된 Access-Control-Request-Headers CORS 요청 헤더의 값을 가져와서 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'}