ASP.NET Web API 2에서 크로스-원본 요청을 사용 하도록 설정Enable cross-origin requests in ASP.NET Web API 2

Mike Wassonby Mike Wasson

브라우저의 보안 기능은 웹 페이지에서 다른 도메인으로 AJAX 요청을 전송하는 것을 막습니다.Browser security prevents a web page from making AJAX requests to another domain. 이 제약 사항을 동일 원본 정책(Same-Origin Policy) 이라고 부르며, 악의적인 사이트가 다른 사이트의 민감한 데이터를 무차별적으로 읽는 것을 방지합니다.This restriction is called the same-origin policy, and prevents a malicious site from reading sensitive data from another site. 그러나 하려는 경우가 있습니다 수 다른 사이트에 web API를 호출할 수 있습니다.However, sometimes you might want to let other sites call your web API.

교차 원본 자원 공유 (CORS, Cross Origin Resource Sharing)는 서버 측에서 동일 원본 정책을 완화할 수 있게 해주는 W3C 표준입니다.Cross Origin Resource Sharing (CORS) is a W3C standard that allows a server to relax the same-origin policy. CORS를 사용하면 서버가 명시적으로 특정 교차 원본 요청만 허용하고, 다른 요청은 거부할 수 있습니다.Using CORS, a server can explicitly allow some cross-origin requests while rejecting others. CORS는 JSONP 같은 기존의 다른 기술보다 안전하고 유연합니다.CORS is safer and more flexible than earlier techniques such as JSONP. 이 자습서에는 Web API 응용 프로그램에서 CORS를 사용 하도록 설정 하는 방법을 보여 줍니다.This tutorial shows how to enable CORS in your Web API application.

이 자습서에서 사용 되는 소프트웨어Software used in the tutorial

소개Introduction

이 자습서에서는 ASP.NET Web API에서 CORS 지원 하는 방법을 보여 줍니다.This tutorial demonstrates CORS support in ASP.NET Web API. 하나의 호출된 "웹 서비스", Web API 컨트롤러를 호스트 하는 다른 호출된 "WebClient", 웹 서비스를 호출 하는 두 개의 ASP.NET 프로젝트-만들어 시작 하겠습니다.We'll start by creating two ASP.NET projects – one called "WebService", which hosts a Web API controller, and the other called "WebClient", which calls WebService. 두 응용 프로그램은 서로 다른 도메인에서 호스트 되므로 WebService에 WebClient에서 AJAX 요청을 한 크로스-원본 요청이입니다.Because the two applications are hosted at different domains, an AJAX request from WebClient to WebService is a cross-origin request.

"동일 원본"이란?What is "same origin"?

두 URL의 스키마, 호스트 및 포트가 모두 동일한 경우, 두 URL의 원본이 동일하다고 말합니다.Two URLs have the same origin if they have identical schemes, hosts, and ports. (RFC 6454)(RFC 6454)

다음 두 URL은 동일한 원본입니다.These two URLs have the same origin:

  • http://example.com/foo.html
  • http://example.com/bar.html

반면, 다음 URL들은 위의 두 URL과는 다른 원본입니다.These URLs have different origins than the previous two:

  • http://example.net -도메인이 다릅니다http://example.net - Different domain
  • http://example.com:9000/foo.html -포트가 다릅니다http://example.com:9000/foo.html - Different port
  • https://example.com/foo.html -스키마가 다릅니다https://example.com/foo.html - Different scheme
  • http://www.example.com/foo.html -하위 도메인이 다릅니다http://www.example.com/foo.html - Different subdomain

Note

Internet Explorer 원본을 비교 하는 경우 포트를 고려 하지 않습니다.Internet Explorer does not consider the port when comparing origins.

웹 서비스 프로젝트를 만들려면Create the WebService project

Note

이 섹션에서는 Web API 프로젝트를 만드는 방법을 이미 알고 가정 합니다.This section assumes you already know how to create Web API projects. 그렇지 않은 경우 ASP.NET Web API를 사용 하 여 시작합니다.If not, see Getting Started with ASP.NET Web API.

  1. Visual Studio를 시작 하 고 새 ASP.NET 웹 응용 프로그램 (.NET Framework) 프로젝트입니다.Start Visual Studio and create a new ASP.NET Web Application (.NET Framework) project.

  2. 새 ASP.NET 웹 응용 프로그램 대화 상자를 선택 합니다 프로젝트 템플릿.In the New ASP.NET Web Application dialog box, select the Empty project template. 아래 폴더를 추가 하 고 핵심에 대 한 참조를 선택 합니다 Web API 확인란을 선택 합니다.Under Add folders and core references for, select the Web API checkbox.

    Visual Studio에서 새 ASP.NET 프로젝트 대화 상자

  3. 명명 된 Web API 컨트롤러 추가 TestController 다음 코드를 사용 하 여:Add a Web API controller named TestController with the following code:

    using System.Net.Http;
    using System.Web.Http;
    
    namespace WebService.Controllers
    {
        public class TestController : ApiController
        {
            public HttpResponseMessage Get()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("GET: Test message")
                };
            }
    
            public HttpResponseMessage Post()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("POST: Test message")
                };
            }
    
            public HttpResponseMessage Put()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("PUT: Test message")
                };
            }
        }
    }
    
  4. 응용 프로그램을 로컬로 실행할 수도 있고 Azure에 배포할 수 있습니다.You can run the application locally or deploy to Azure. (이 자습서의 스크린샷에서, 앱 배포에 Azure App Service Web Apps입니다.) Web API가 작동 하는지 확인 하려면로 이동 http://hostname/api/test/여기서 호스트 이름 응용 프로그램을 배포한 도메인입니다.(For the screenshots in this tutorial, the app deploys to Azure App Service Web Apps.) To verify that the web API is working, navigate to http://hostname/api/test/, where hostname is the domain where you deployed the application. 응답 텍스트가 "가져오기: 테스트 메시지"합니다.You should see the response text, "GET: Test Message".

    웹 브라우저 보여 주는 테스트 메시지

WebClient 프로젝트를 만들려면Create the WebClient project

  1. 만들면 ASP.NET 웹 응용 프로그램 (.NET Framework) 프로젝트를 마우스 합니다 MVC 프로젝트 템플릿.Create another ASP.NET Web Application (.NET Framework) project and select the MVC project template. 필요에 따라 선택할 인증 변경 > 인증 안 함합니다.Optionally, select Change Authentication > No Authentication. 이 자습서에 대 한 인증이 필요는 없습니다.You don't need authentication for this tutorial.

    Visual Studio에서 새 ASP.NET 프로젝트 대화 상자에서 MVC 템플릿

  2. 솔루션 탐색기, 파일을 열고 Views/Home/Index.cshtml합니다.In Solution Explorer, open the file Views/Home/Index.cshtml. 이 파일의 코드를 다음으로 바꿉니다.Replace the code in this file with the following:

    <div>
        <select id="method">
            <option value="get">GET</option>
            <option value="post">POST</option>
            <option value="put">PUT</option>
        </select>
        <input type="button" value="Try it" onclick="sendRequest()" />
        <span id='value1'>(Result)</span>
    </div>
    
    @section scripts {
    <script>
        // TODO: Replace with the URL of your WebService app
        var serviceUrl = 'http://mywebservice/api/test'; 
    
        function sendRequest() {
            var method = $('#method').val();
    
            $.ajax({
                type: method,
                url: serviceUrl
            }).done(function (data) {
                $('#value1').text(data);
            }).fail(function (jqXHR, textStatus, errorThrown) {
                $('#value1').text(jqXHR.responseText || textStatus);
            });
        }
    </script>
    }
    

    에 대 한 합니다 serviceUrl 변수를 웹 서비스 응용 프로그램의 URI를 사용 합니다.For the serviceUrl variable, use the URI of the WebService app.

  3. WebClient 앱을 로컬로 실행 하거나 다른 웹 사이트에 게시 합니다.Run the WebClient app locally or publish it to another website.

"Try It" 단추를 클릭 하면 AJAX 요청에 나열 된 HTTP 메서드를 사용 하 여 웹 서비스 앱에 전송 됩니다 (GET, POST 또는 PUT) 드롭다운 상자입니다.When you click the "Try It" button, an AJAX request is submitted to the WebService app using the HTTP method listed in the dropdown box (GET, POST, or PUT). 이렇게 하면 다양 한 원본 간 요청을 검사할 수 있습니다.This lets you examine different cross-origin requests. 현재 웹 서비스 응용 프로그램 단추를 클릭 하면 오류가 발생 하므로 CORS를 지원 하지 않습니다.Currently, the WebService app does not support CORS, so if you click the button you'll get an error.

브라우저에서 오류 '평가판 사용해 보기'

Note

와 같은 도구에서 HTTP 트래픽을 시청 하는 경우 Fiddler, 브라우저는 GET 요청을 보내지 및 요청이 성공 하면 있지만 AJAX 호출이 오류를 반환 합니다. 확인할 수 있습니다.If you watch the HTTP traffic in a tool like Fiddler, you'll see that the browser does send the GET request, and the request succeeds, but the AJAX call returns an error. 동일 원본 정책에서 브라우저 해도 알아야 할 것 보내는 요청 합니다.It's important to understand that same-origin policy does not prevent the browser from sending the request. 대신 보지 못하도록 응용 프로그램을 방지 합니다 응답합니다.Instead, it prevents the application from seeing the response.

웹 요청을 보여 주는 fiddler 웹 디버거

CORS를 사용 하도록 설정Enable CORS

이제 웹 서비스 앱에서 CORS를 사용 하겠습니다.Now let's enable CORS in the WebService app. 첫째, CORS NuGet 패키지를 추가 합니다.First, add the CORS NuGet package. Visual Studio에서에서 합니다 도구 메뉴에서 NuGet 패키지 관리자을 선택한 후 패키지 관리자 콘솔합니다.In Visual Studio, from the Tools menu, select NuGet Package Manager, then select Package Manager Console. 패키지 관리자 콘솔 창에서 다음 명령을 입력 합니다.In the Package Manager Console window, type the following command:

Install-Package Microsoft.AspNet.WebApi.Cors

이 명령은 최신 패키지를 설치 하 고 core Web API 라이브러리를 포함 한 모든 종속성을 업데이트 합니다.This command installs the latest package and updates all dependencies, including the core Web API libraries. 사용 된 -Version 특정 버전을 대상으로 하는 플래그입니다.Use the -Version flag to target a specific version. CORS 패키지에는 Web API 2.0 이상이 필요합니다.The CORS package requires Web API 2.0 or later.

파일을 엽니다 앱_Start/WebApiConfig.cs합니다.Open the file App_Start/WebApiConfig.cs. 다음 코드를 추가 합니다 WebApiConfig.Register 메서드:Add the following code to the WebApiConfig.Register method:

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

다음을 추가 합니다 [EnableCors] 특성을 TestController 클래스:Next, add the [EnableCors] attribute to the TestController class:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

에 대 한 합니다 원본을 매개 변수를 WebClient 응용 프로그램을 배포한 URI를 사용 합니다.For the origins parameter, use the URI where you deployed the WebClient application. 따라서 크로스-원본 요청에서 WebClient는 여전히 다른 모든 도메인 간 요청을 허용 하는 동안.This allows cross-origin requests from WebClient, while still disallowing all other cross-domain requests. 나중에 대 한 매개 변수를 설명할 [EnableCors] 자세히입니다.Later, I'll describe the parameters for [EnableCors] in more detail.

끝에 슬래시를 포함 하지 않는 합니다 원본을 URL입니다.Do not include a forward slash at the end of the origins URL.

업데이트 된 웹 서비스 응용 프로그램을 다시 배포 합니다.Redeploy the updated WebService application. WebClient를 업데이트할 필요가 없습니다.You don't need to update WebClient. 이제 WebClient에서 AJAX 요청이 성공 해야 합니다.Now the AJAX request from WebClient should succeed. GET, PUT 및 POST 메서드가 모두 허용 됩니다.The GET, PUT, and POST methods are all allowed.

웹 브라우저 표시 성공적인 테스트 메시지

CORS의 작동 원리How CORS Works

이 섹션에서는 HTTP 메시지 수준에서 CORS 요청에서 어떻게 설명 합니다.This section describes what happens in a CORS request, at the level of the HTTP messages. 구성할 수 있도록 CORS의 작동 방식을 이해 해야 합니다 [EnableCors] 올바르게 특성 및 예상 대로 작동 되지 않으면 문제를 해결 합니다.It's important to understand how CORS works, so that you can configure the [EnableCors] attribute correctly and troubleshoot if things don't work as you expect.

CORS 명세에서는 교차 원본 요청을 활성화시키기 위한 용도로 몇 가지 새로운 HTTP 헤더들이 도입되었습니다.The CORS specification introduces several new HTTP headers that enable cross-origin requests. 브라우저에서 CORS를 지 원하는 경우 크로스-원본 요청에 대해 자동으로 이러한 헤더 설정 모든 JavaScript 코드에 특별 한 작업을 수행할 필요가 없습니다.If a browser supports CORS, it sets these headers automatically for cross-origin requests; you don't need to do anything special in your JavaScript code.

크로스-원본 요청 예제는 다음과 같습니다.Here is an example of a cross-origin request. "원본" 헤더를 요청 하는 사이트의 도메인을 제공 합니다.The "Origin" header gives the domain of the site that is making the request.

GET http://myservice.azurewebsites.net/api/test HTTP/1.1
Referer: http://myclient.azurewebsites.net/
Accept: */*
Accept-Language: en-US
Origin: http://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

서버 요청을 허용 하면, 액세스 제어-허용-원본 헤더를 설정 합니다.If the server allows the request, it sets the Access-Control-Allow-Origin header. 이 헤더의 값 또는 원본 헤더와 일치 하는 와일드 카드 값 "*", 즉 모든 원본을 허용 됩니다.The value of this header either matches the Origin header, or is the wildcard value "*", meaning that any origin is allowed.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Date: Wed, 05 Jun 2013 06:27:30 GMT
Content-Length: 17

GET: Test message

응답에서 액세스 제어-허용-원본 헤더를 포함 하지 않습니다, AJAX 요청이 실패 합니다.If the response does not include the Access-Control-Allow-Origin header, the AJAX request fails. 특히 브라우저 요청을 허용 하지 않습니다.Specifically, the browser disallows the request. 서버 응답에 성공 하면 반환 하는 경우에 브라우저 해도 응답 클라이언트 응용 프로그램에 사용할 수 있습니다.Even if the server returns a successful response, the browser does not make the response available to the client application.

실행 전 요청Preflight Requests

브라우저는 일부 CORS 요청에 대 한 리소스에 대 한 실제 요청을 보내기 전에 "실행 전 요청을" 라는 추가 요청을 보냅니다.For some CORS requests, the browser sends an additional request, called a "preflight request", before it sends the actual request for the resource.

다음 조건이 true 인 경우 브라우저가 실행 전 요청을 건너뛸 수 있습니다.:The browser can skip the preflight request if the following conditions are true:

  • 요청 메서드는 GET, HEAD 또는 POST The request method is GET, HEAD, or POST, and

  • 응용 프로그램 동의 수용-언어 Content-language 이외의 모든 요청 헤더를 설정 하지 않습니다 Content-type, 또는 마지막-이벤트-ID The application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, and

  • Content-type 헤더 (하는 경우 설정) 다음 중 하나입니다.The Content-Type header (if set) is one of the following:

    • application/x-www-form-urlencodedapplication/x-www-form-urlencoded
    • 다중 파트/폼 데이터multipart/form-data
    • 텍스트/일반text/plain

요청 헤더에 대 한 규칙을 호출 하 여 응용 프로그램을 설정 하는 헤더 적용할 setRequestHeaderXMLHttpRequest 개체입니다.The rule about request headers applies to headers that the application sets by calling setRequestHeader on the XMLHttpRequest object. (CORS 사양 이러한 "작성자 요청 헤더"를 호출 합니다.) 헤더에 규칙이 적용 되지 않습니다 합니다 브라우저 사용자 에이전트, 호스트 또는 콘텐츠-길이 같은 설정할 수 있습니다.(The CORS specification calls these "author request headers".) The rule does not apply to headers the browser can set, such as User-Agent, Host, or Content-Length.

실행 전 요청의 예제는 다음과 같습니다.Here is an example of a preflight request:

OPTIONS http://myservice.azurewebsites.net/api/test HTTP/1.1
Accept: */*
Origin: http://myclient.azurewebsites.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

HTTP OPTIONS 메서드를 사용 하는 사전 요청 합니다.The pre-flight request uses the HTTP OPTIONS method. 두 가지 특수 헤더를 포함합니다.It includes two special headers:

  • 액세스-컨트롤-요청-방법: 실제 요청에 사용 될 HTTP 메서드.Access-Control-Request-Method: The HTTP method that will be used for the actual request.
  • Access-Control-Request-Headers: 요청 헤더의 목록을 하는 응용 프로그램 실제 요청을 설정 합니다.Access-Control-Request-Headers: A list of request headers that the application set on the actual request. (마찬가지로이 브라우저 설정 하는 헤더)(Again, this does not include headers that the browser sets.)

예제 응답, 서버 요청을 허용 하는 다음과 같습니다.Here is an example response, assuming that the server allows the request:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT
Date: Wed, 05 Jun 2013 06:33:22 GMT

허용 된 메서드를 나열 하는 액세스-컨트롤-허용-메서드 헤더 및 필요에 따라 허용 되는 헤더를 나열 하는 액세스 제어-허용-헤더 헤더를 응답에 포함 됩니다.The response includes an Access-Control-Allow-Methods header that lists the allowed methods, and optionally an Access-Control-Allow-Headers header, which lists the allowed headers. 실행 전 요청이 성공 하면 브라우저 앞에서 설명한 대로 실제 요청을 보냅니다.If the preflight request succeeds, the browser sends the actual request, as described earlier.

실행 전 OPTIONS 요청을 사용 하 여 끝점을 테스트 하려면 일반적으로 사용 되는 도구 (예를 들어 Fiddler 하 고 Postman) 기본적으로 필수 옵션 헤더를 보내지 않습니다.Tools commonly used to test endpoints with preflight OPTIONS requests (for example, Fiddler and Postman) don't send the required OPTIONS headers by default. 있는지 확인 합니다 Access-Control-Request-MethodAccess-Control-Request-Headers 헤더 요청과 함께 전송 되 고 옵션 헤더 IIS 통해 앱에 도달 하는 합니다.Confirm that the Access-Control-Request-Method and Access-Control-Request-Headers headers are sent with the request and that OPTIONS headers reach the app through IIS.

ASP.NET 앱을 받고 옵션 요청을 처리 하도록 IIS를 구성 하려면 앱의 다음 구성을 추가 web.config 파일을 <system.webServer><handlers> 섹션:To configure IIS to allow an ASP.NET app to receive and handle OPTION requests, add the following configuration to the app's web.config file in the <system.webServer><handlers> section:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

제거 OPTIONSVerbHandler IIS OPTIONS 요청을 처리 하는 것을 금지 합니다.The removal of OPTIONSVerbHandler prevents IIS from handling OPTIONS requests. 대체 ExtensionlessUrlHandler-Integrated-4.0 OPTIONS 요청 기본 모듈 등록 확장명 없는 Url 사용 하 여 GET, HEAD, POST 및 디버그 요청만 허용 하기 때문에 앱을 연결할 수 있습니다.The replacement of ExtensionlessUrlHandler-Integrated-4.0 allows OPTIONS requests to reach the app because the default module registration only allows GET, HEAD, POST, and DEBUG requests with extensionless URLs.

[EnableCors]에 대 한 범위 규칙Scope Rules for [EnableCors]

응용 프로그램에서 작업당: 컨트롤러 당 또는 모든 Web API 컨트롤러에 대 한 전역적으로 CORS를 설정할 수 있습니다.You can enable CORS per action, per controller, or globally for all Web API controllers in your application.

작업당Per Action

단일 작업에 대 한 CORS를 사용 하도록 설정 합니다 [EnableCors] 동작 메서드에 대 한 특성입니다.To enable CORS for a single action, set the [EnableCors] attribute on the action method. 다음 예제에서는 CORS는 GetItem 방법만 해당 합니다.The following example enables CORS for the GetItem method only.

public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }

    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
    public HttpResponseMessage GetItem(int id) { ... }

    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage PutItem(int id) { ... }
}

컨트롤러당Per Controller

설정 하는 경우 [EnableCors] 컨트롤러 클래스에 대해 컨트롤러에서 모든 작업에 적용 합니다.If you set [EnableCors] on the controller class, it applies to all the actions on the controller. CORS를 사용 하지 않으려면 작업을 추가 합니다 [DisableCors] 특성 작업을 합니다.To disable CORS for an action, add the [DisableCors] attribute to the action. 다음 예제에서는 제외한 모든 방법에 대 한 CORS를 사용 하면 PutItem합니다.The following example enables CORS for every method except PutItem.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }
    public HttpResponseMessage GetItem(int id) { ... }
    public HttpResponseMessage Post() { ... }

    [DisableCors]
    public HttpResponseMessage PutItem(int id) { ... }
}

전 세계Globally

CORS를 사용 하도록 응용 프로그램에서 모든 Web API 컨트롤러에 대 한 전달를 EnableCorsAttribute 인스턴스를 EnableCors 메서드:To enable CORS for all Web API controllers in your application, pass an EnableCorsAttribute instance to the EnableCors method:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

둘 이상의 범위에서 특성을 설정 하는 경우 우선 순위가 같습니다.If you set the attribute at more than one scope, the order of precedence is:

  1. 작업Action
  2. 컨트롤러Controller
  3. GlobalGlobal

허용되는 원본 설정하기Set the allowed origins

원본을 의 매개 변수를 [EnableCors] 특성 리소스에 액세스할 수 있는 원본 허용 되는지 지정 합니다.The origins parameter of the [EnableCors] attribute specifies which origins are allowed to access the resource. 값은 허용 되는 원본의 쉼표로 구분 된 목록.The value is a comma-separated list of the allowed origins.

[EnableCors(origins: "http://www.contoso.com,http://www.example.com", 
    headers: "*", methods: "*")]

와일드 카드 값을 사용할 수도 있습니다 "*" 요청을 모든 원본을 허용 하도록 합니다.You can also use the wildcard value "*" to allow requests from any origins.

모든 원본의 요청을 허용하기 전에 신중히 고민하시기 바랍니다.Consider carefully before allowing requests from any origin. 말 그대로 모든 웹 사이트에 web API에 대 한 AJAX 호출을 설정할 수 있는지를 의미 합니다.It means that literally any website can make AJAX calls to your web API.

// Allow CORS for all origins. (Caution!)
[EnableCors(origins: "*", headers: "*", methods: "*")]

허용되는 HTTP 메서드 설정하기Set the allowed HTTP methods

합니다 메서드 의 매개 변수를 [EnableCors] 리소스에 액세스할 수 있는 HTTP 메서드 특성 지정 합니다.The methods parameter of the [EnableCors] attribute specifies which HTTP methods are allowed to access the resource. 모든 메서드를 허용 하려면 와일드 카드 값을 사용 하 여 "*"입니다.To allow all methods, use the wildcard value "*". 다음 예제에서는 GET 및 POST 요청만 허용 합니다.The following example allows only GET and POST requests.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "get,post")]
public class TestController : ApiController
{
    public HttpResponseMessage Get() { ... }
    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage Put() { ... }    
}

허용되는 요청 헤더 설정하기Set the allowed request headers

이 문서에서는 실행 전 요청을 응용 프로그램에 의해 설정 된 HTTP 헤더를 나열 하는 액세스 제어-요청 헤더 헤더에 포함 될 수 있습니다 이전 하는 방법을 설명 (소위 "요청 헤더 author").This article described earlier how a preflight request might include an Access-Control-Request-Headers header, listing the HTTP headers set by the application (the so-called "author request headers"). 합니다 헤더 의 매개 변수를 [EnableCors] 특성은 만든 요청 헤더를 허용 하도록 지정 합니다.The headers parameter of the [EnableCors] attribute specifies which author request headers are allowed. 모든 헤더를 허용 하려면 설정 헤더 에 "*"입니다.To allow any headers, set headers to "*". 허용 목록에 추가할 특정 헤더를 설정 헤더 허용 되는 헤더의 쉼표로 구분 된 목록에:To whitelist specific headers, set headers to a comma-separated list of the allowed headers:

[EnableCors(origins: "http://example.com", 
    headers: "accept,content-type,origin,x-my-header", methods: "*")]

그러나 브라우저에 대 한 액세스 제어-요청 헤더는 설정 하는 방법을 완전히 일치 하지 않습니다.However, browsers are not entirely consistent in how they set Access-Control-Request-Headers. 예를 들어, Chrome는 현재 "원본"을 포함합니다.For example, Chrome currently includes "origin". FireFox 응용 프로그램이 스크립트를 설정 하는 경우에 "Accept"와 같은 표준 헤더를 포함 되지 않습니다.FireFox does not include standard headers such as "Accept", even when the application sets them in script.

설정 하는 경우 헤더 이외의 값으로 "*"를 포함 해야 적어도 "수락", "콘텐츠-유형" 및 "원본"을 지원 하려는 모든 사용자 지정 헤더입니다.If you set headers to anything other than "*", you should include at least "accept", "content-type", and "origin", plus any custom headers that you want to support.

허용 되는 응답 헤더 설정Set the allowed response headers

기본적으로 브라우저 노출 하지 않습니다 모든 응용 프로그램에 대 한 응답 헤더입니다.By default, the browser does not expose all of the response headers to the application. 기본적으로 사용 가능한 응답 헤더들은 다음과 같습니다.The response headers that are available by default are:

  • Cache-ControlCache-Control
  • 콘텐츠 언어Content-Language
  • 콘텐츠 형식Content-Type
  • ExpiresExpires
  • Last-ModifiedLast-Modified
  • PragmaPragma

CORS 명세에서는 이 헤더들을 단순 응답 헤더(Simple Response Header) 라고 부릅니다.The CORS spec calls these simple response headers. 다른 헤더에서 응용 프로그램에 사용할 수 있도록 설정 합니다 exposedHeaders 의 매개 변수 [EnableCors] 합니다.To make other headers available to the application, set the exposedHeaders parameter of [EnableCors].

다음 예제에서는 컨트롤러의에서 Get 메서드 ' X 사용자 지정 헤더 ' 라는 사용자 지정 헤더를 설정 합니다.In the following example, the controller's Get method sets a custom header named ‘X-Custom-Header'. 기본적으로 브라우저는 크로스-원본 요청에서이 헤더를 노출 하지 않습니다.By default, the browser will not expose this header in a cross-origin request. 헤더에서 사용할 수 있도록 하려면에 ' X 사용자 지정 헤더 '를 포함 exposedHeaders합니다.To make the header available, include ‘X-Custom-Header' in exposedHeaders.

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-Custom-Header")]
public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        var resp = new HttpResponseMessage()
        {
            Content = new StringContent("GET: Test message")
        };
        resp.Headers.Add("X-Custom-Header", "hello");
        return resp;
    }
}

크로스-원본 요청에 자격 증명을 전달 합니다.Pass credentials in cross-origin requests

CORS 요청에서 자격 증명(Credentials)은 특별한 처리를 해야 합니다.Credentials require special handling in a CORS request. 기본적으로 브라우저는 크로스-원본 요청을 사용 하 여 자격 증명을 보내지 않습니다.By default, the browser does not send any credentials with a cross-origin request. 여기에서 말하는 자격 증명에는 쿠키뿐만 아니라 HTTP 인증 스킴도 포함됩니다.Credentials include cookies as well as HTTP authentication schemes. 크로스-원본 요청을 사용 하 여 자격 증명을 보내려면 클라이언트 설정 해야 합니다 XMLHttpRequest.withCredentials true로 합니다.To send credentials with a cross-origin request, the client must set XMLHttpRequest.withCredentials to true.

사용 하 여 XMLHttpRequest 직접.Using XMLHttpRequest directly:

var xhr = new XMLHttpRequest();
xhr.open('get', 'http://www.example.com/api/test');
xhr.withCredentials = true;

jQuery를 사용할 경우:In jQuery:

$.ajax({
    type: 'get',
    url: 'http://www.example.com/api/test',
    xhrFields: {
        withCredentials: true
    }

또한 서버에서도 자격 증명을 허용해야만 합니다.In addition, the server must allow the credentials. Web API에서 크로스-원본 자격 증명을 허용 하려면 설정 합니다 SupportsCredentials 속성에서 true로 합니다 [EnableCors] 특성:To allow cross-origin credentials in Web API, set the SupportsCredentials property to true on the [EnableCors] attribute:

[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", 
    methods: "*", SupportsCredentials = true)]

이 속성이 true 이면 HTTP 응답에 대 한 액세스 제어-허용-자격 증명 헤더가 포함 됩니다.If this property is true, the HTTP response will include an Access-Control-Allow-Credentials header. 이 헤더는 서버를 크로스-원본 요청에 대 한 자격 증명을 허용 하는지 브라우저를 알립니다.This header tells the browser that the server allows credentials for a cross-origin request.

브라우저에서 자격 증명을 보내는 응답을 유효한 액세스-컨트롤--자격 증명 허용 헤더를 포함 하지 않습니다 하지만 브라우저 응용 프로그램에 대 한 응답을 노출 하지 않습니다 고 AJAX 요청이 실패 합니다.If the browser sends credentials, but the response does not include a valid Access-Control-Allow-Credentials header, the browser will not expose the response to the application, and the AJAX request fails.

설정에 대 한 주의 SupportsCredentials 다른 도메인에서 웹 사이트 사용자가 인식 하지 않고 사용자 대신 Web API에는 로그인 한 사용자의 자격 증명에 보낼 수 있기 때문에 true로 합니다.Be careful about setting SupportsCredentials to true, because it means a website at another domain can send a logged-in user's credentials to your Web API on the user's behalf, without the user being aware. CORS 사양에는 또한 해당 설정 상태 원본을 에 " * " 올바르지 경우 SupportsCredentials 그렇습니다.The CORS spec also states that setting origins to "*" is invalid if SupportsCredentials is true.

사용자 지정 CORS 정책 공급자Custom CORS policy providers

합니다 [EnableCors] 구현 특성을 ICorsPolicyProvider 인터페이스입니다.The [EnableCors] attribute implements the ICorsPolicyProvider interface. 파생 되는 클래스를 만들어 사용자 지정 구현을 제공할 수 있습니다 특성 구현 ICorsPolicyProvider합니다.You can provide your own implementation by creating a class that derives from Attribute and implements ICorsPolicyProvider.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MyCorsPolicyAttribute : Attribute, ICorsPolicyProvider 
{
    private CorsPolicy _policy;

    public MyCorsPolicyAttribute()
    {
        // Create a CORS policy.
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };

        // Add allowed origins.
        _policy.Origins.Add("http://myclient.azurewebsites.net");
        _policy.Origins.Add("http://www.contoso.com");
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {
        return Task.FromResult(_policy);
    }
}

이제 배치 하는 위치 특성을 적용할 수 있습니다 [EnableCors] 합니다.Now you can apply the attribute any place that you would put [EnableCors].

[MyCorsPolicy]
public class TestController : ApiController
{
    .. //

예를 들어, 사용자 지정 CORS 정책 공급자를 구성 파일에서 설정을 읽을 수 없습니다.For example, a custom CORS policy provider could read the settings from a configuration file.

특성을 사용 하는 대신,으로 등록할 수 있습니다는 ICorsPolicyProviderFactory 개체를 만드는 ICorsPolicyProvider 개체입니다.As an alternative to using attributes, you can register an ICorsPolicyProviderFactory object that creates ICorsPolicyProvider objects.

public class CorsPolicyFactory : ICorsPolicyProviderFactory
{
    ICorsPolicyProvider _provider = new MyCorsPolicyProvider();

    public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {
        return _provider;
    }
}

설정 하는 ICorsPolicyProviderFactory를 호출 합니다 SetCorsPolicyProviderFactory 같이 시작 시 확장 메서드:To set the ICorsPolicyProviderFactory, call the SetCorsPolicyProviderFactory extension method at startup, as follows:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
        config.EnableCors();

        // ...
    }
}

브라우저 지원Browser support

Web API CORS 패키지에는 서버 쪽 기술입니다.The Web API CORS package is a server-side technology. 사용자의 브라우저는 또한 CORS를 지원 해야 합니다.The user's browser also needs to support CORS. 다행 스럽게도 모든 주요 브라우저의 현재 버전 포함 CORS에 대 한 지원합니다.Fortunately, the current versions of all major browsers include support for CORS.