ASP.Net MVC에서 Access-Control-Allow-Origin 설정-가장 간단한 방법


206

나는 간단한 동작 방법을 가지고 있는데, 그것은 json을 반환합니다. ajax.example.com에서 실행됩니다. 다른 사이트 someothersite.com에서이 사이트에 액세스해야합니다.

전화하려고하면 예상대로 얻을 수 있습니다 ... :

Origin http://someothersite.com is not allowed by Access-Control-Allow-Origin.

이 문제를 해결하는 두 가지 방법 인 JSONP 와 헤더를 설정하기 위해 사용자 정의 HttpHandler 를 작성하는 방법을 알고 있습니다.

더 간단한 방법이 없습니까?

간단한 조치로 허용 된 원점 목록을 정의하거나 모든 사람을 허용 할 수 없습니까? 액션 필터일까요?

최적은 ... :

return json(mydata, JsonBehaviour.IDontCareWhoAccessesMe);

1
vNext 및 MVC6을 확인하십시오 : neelbhatt40.wordpress.com/2015/09/10/…
Neel

답변:


381

일반 ASP.NET MVC 컨트롤러

새로운 속성을 만듭니다

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);
    }
}

작업에 태그를 지정하십시오.

[AllowCrossSiteJson]
public ActionResult YourMethod()
{
    return Json("Works better?");
}

ASP.NET 웹 API

using System;
using System.Web.Http.Filters;

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null)
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        base.OnActionExecuted(actionExecutedContext);
    }
}

전체 API 컨트롤러에 태그를 지정하십시오.

[AllowCrossSiteJson]
public class ValuesController : ApiController
{

또는 개별 API 호출 :

[AllowCrossSiteJson]
public IEnumerable<PartViewModel> Get()
{
    ...
}

Internet Explorer <= v9의 경우

IE <= 9는 CORS를 지원하지 않습니다. 프록시를 통해 해당 요청을 자동으로 라우팅하는 자바 스크립트를 작성했습니다. 모두 100 % 투명합니다 (내 프록시와 스크립트 만 포함하면됩니다).

너겟을 사용하여 다운로드 corsproxy하고 포함 된 지침을 따르십시오.

블로그 게시물 | 소스 코드


8
놀랄 만한! 나는 MVC + U를 좋아한다!
Piotr Kula

2
이 솔루션의 우아함을 경외하여
BraveNewMath

3
CORS를 자신의 도메인으로 제한하려는 경우 특정 출처를 허용하도록 속성을 쉽게 확장 할 수 있습니다.
Petrus Theron

2
App_Start \ FilterConfig의 RegisterHttpFilters에 이것을 추가 할 수 있어야합니까? 그렇게하면 프로젝트의 모든 Api 컨트롤러에 적용됩니다. 이것을 페이트의 주석과 결합하면 CORS를 모든 컨트롤러의 도메인으로 제한 할 수 있습니다.
bdwakefield

9
최근에 프로젝트를 MVC 5로 업데이트하고 시도했습니다. 필터에 헤더를 추가해도 작동하지 않는 것 같습니다. 네트워크에서 요청을 볼 때 헤더가 응답에 없습니다. 이 작업을 수행하기 위해 필요한 다른 것이 있습니까?
Kneemin

121

IIS 7 이상을 사용하는 경우 system.webServer 섹션에서 web.config 파일을 폴더의 루트에 넣을 수 있습니다.

<httpProtocol>
   <customHeaders>
      <clear />
      <add name="Access-Control-Allow-Origin" value="*" />
   </customHeaders>
</httpProtocol>

참조 : http://msdn.microsoft.com/en-us/library/ms178685.aspxhttp://enable-cors.org/#how-iis7


1
더 이상 이유를 기억할 수 없지만이 방법이 IIS 7 이상에서는 항상 작동하는 것은 아닙니다.
LaundroMatt

흠. 내가 작동하지 않을 것이라고 생각할 수있는 유일한 이유는 요청이 비 CORS 브라우저에서 시작된 경우입니다. 하지만 계속 조사하겠습니다.
sellmeadog

29
또한 이것은 전체 웹 사이트를 CORS 친화적으로 만들 것입니다. 누군가 단일 동작 또는 컨트롤러 만 CORS 친화적으로 표시하려는 경우 허용되는 답변이 훨씬 좋습니다.
Lev Dubinets

1
ASP.Net 섹션 이 표시되면 힌트가 있습니다 . "참고 :이 방법은 IIS6, IIS7 클래식 모드 및 IIS7 통합 모드와 호환됩니다."
percebus

1
SharePoint 환경에 앱을 게시 할 때 도메인 간 문제가 발생합니다. 로컬 환경에서 내 앱을 실행하면 내 앱이 제대로 실행되지만 azure에서 공유 지점 사이트로 게시하면 Ajax.Begin 폼 호출의 오류 페이지로 리디렉션됩니다. 이 솔루션을 시도했지만 작동하지 않습니다. 그것에 대한 다른 대안이 있습니까?
Jyotsna Wadhwani

22

요청이 쿠키를 통과했을 때 검색 한 콘텐츠 (예 : xhr에 있음 withCredentials=true)를 브라우저가 거부 하고 사이트가로 Access-Control-Allow-Origin설정되는 문제가 발생했습니다 *. Chrome의 오류는 "자격 증명 플래그가 true 인 경우 Access-Control-Allow-Origin에서 와일드 카드를 사용할 수 없습니다."입니다.

@jgauffin의 답변을 바탕으로 이것을 만들었습니다. 기본적으로 특정 브라우저 보안 검사를 해결하는 방법이므로주의하십시오.

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // We'd normally just use "*" for the allow-origin header, 
        // but Chrome (and perhaps others) won't allow you to use authentication if
        // the header is set to "*".
        // TODO: Check elsewhere to see if the origin is actually on the list of trusted domains.
        var ctx = filterContext.RequestContext.HttpContext;
        var origin = ctx.Request.Headers["Origin"];
        var allowOrigin = !string.IsNullOrWhiteSpace(origin) ? origin : "*";
        ctx.Response.AddHeader("Access-Control-Allow-Origin", allowOrigin);
        ctx.Response.AddHeader("Access-Control-Allow-Headers", "*");
        ctx.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        base.OnActionExecuting(filterContext);
    }
}

이것은 특히 유용했습니다. 감사합니다.
cklimowski

15

이것은 정말 간단합니다. web.config에 추가하십시오.

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://localhost" />
      <add name="Access-Control-Allow-Headers" value="X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent" />
      <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
      <add name="Access-Control-Max-Age" value="1000" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Origin에서는 웹 서버에 액세스 할 수있는 모든 도메인을 헤더에 넣고 헤더에는 ajax http 요청에서 사용할 수있는 가능한 모든 헤더를 넣고 메소드에 서버에서 허용하는 모든 메소드를 넣습니다.

안부 :)


인증 된 쿼리를 사용하려는 경우 Access-Control-Allow-Headers에 "권한 부여"를 추가하는 것도 유용 할 수 있습니다.
AFract

9

때로는 옵션 동사도 문제를 일으킨다

간단히 : 다음으로 web.config를 업데이트하십시오.

<system.webServer>
    <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

httpGet 및 httpOptions로 웹 서비스 / 컨트롤러 헤더를 업데이트하십시오.

// GET api/Master/Sync/?version=12121
        [HttpGet][HttpOptions]
        public dynamic Sync(string version) 
        {

BTW, sitefinity에서는 보안 섹션의 시스템 고급 설정에 *를 추가해야합니다
Bishoy Hanna

컨트롤러 헤더를 업데이트해야하는 파일은 무엇입니까?
user3281466 8


5

API를 사용하는 경우 메소드에이 행을 추가하십시오.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 

4

이 튜토리얼 은 매우 유용합니다. 빠른 요약을 제공하려면

  1. Nuget에서 사용 가능한 CORS 패키지를 사용하십시오. Install-Package Microsoft.AspNet.WebApi.Cors

  2. 당신에 WebApiConfig.cs파일 추가 config.EnableCors()받는 Register()방법.

  3. cors를 처리해야하는 컨트롤러에 속성을 추가하십시오.

[EnableCors(origins: "<origin address in here>", headers: "*", methods: "*")]


요청에 사용자 정의 헤더를 설정해야했기 때문에이 방법을 사용해야했으며 사용자 정의 속성 메소드가 브라우저 사전 비행 요청에서 작동하지 않았습니다. 이것은 모든 경우에 작동하는 것 같습니다.
lehn0058

3
    public ActionResult ActionName(string ReqParam1, string ReqParam2, string ReqParam3, string ReqParam4)
    {
        this.ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
         /*
                --Your code goes here --
         */
        return Json(new { ReturnData= "Data to be returned", Success=true }, JsonRequestBehavior.AllowGet);
    }

2

Access-Control-Expose-Headers를 전달할 수있는 여러 가지 방법이 있습니다.

  • jgauffin이 설명했듯이 새로운 속성을 만들 수 있습니다.
  • LaundroMatt가 설명했듯이 web.config 파일에 추가 할 수 있습니다.
  • 또 다른 방법은 webApiconfig.cs 파일에서 아래와 같이 코드를 추가 할 수 있습니다.

    config.EnableCors (new EnableCorsAttribute ( " ", 헤더 : " ", 메소드 : "*", exposedHeaders : "TestHeaderToExpose") {SupportsCredentials = true});

또는 Global.Asax 파일에 아래 코드를 추가 할 수 있습니다.

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                //These headers are handling the "pre-flight" OPTIONS call sent by the browser
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
                HttpContext.Current.Response.End();
            }
        }

나는 옵션을 위해 그것을 썼다. 필요에 따라 동일하게 수정하십시오.

행복한 코딩!


1

저녁 내내 고군분투하고 난 후에 마침내 이것을 작동하게했습니다. 디버깅 후 내가 겪고있는 문제는 클라이언트가 소위 프리 플라이트 옵션 요청을 보내 응용 프로그램이 제공된 원본, 메소드 및 헤더와 함께 게시 요청을 보낼 수 있는지 확인하는 것이 었습니다. Owin 또는 APIController를 사용하고 싶지 않았으므로 발굴을 시작하고 ActionFilterAttribute만으로 다음 솔루션을 생각해 냈습니다. 특히 "Access-Control-Allow-Headers"부분은 언급 된 헤더가 요청이 보낼 헤더와 일치해야하므로 매우 중요합니다.

using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyNamespace
{
    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpRequest request = HttpContext.Current.Request;
            HttpResponse response = HttpContext.Current.Response;

            // check for preflight request
            if (request.Headers.AllKeys.Contains("Origin") && request.HttpMethod == "OPTIONS")
            {
                response.AppendHeader("Access-Control-Allow-Origin", "*");
                response.AppendHeader("Access-Control-Allow-Credentials", "true");
                response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
                response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
                response.End();
            }
            else
            {
                HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                HttpContext.Current.Response.Cache.SetNoStore();

                response.AppendHeader("Access-Control-Allow-Origin", "*");
                response.AppendHeader("Access-Control-Allow-Credentials", "true");
                if (request.HttpMethod == "POST")
                {
                    response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
                    response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
                }

                base.OnActionExecuting(filterContext);
            }
        }
    }
}

마지막으로 내 MVC 작업 방법은 다음과 같습니다. 프리 플라이트 요청이 실패하므로 옵션 HttpVerbs도 언급해야합니다.

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Options)]
[AllowCrossSiteJson]
public async Task<ActionResult> Create(MyModel model)
{
    return Json(await DoSomething(model));
}

0

Web.config에 다음을 입력하십시오

<system.webServer>
<httpProtocol>
  <customHeaders>
    <clear />     
    <add name="Access-Control-Allow-Credentials" value="true" />
    <add name="Access-Control-Allow-Origin" value="http://localhost:123456(etc)" />
  </customHeaders>
</httpProtocol>

0

IIS를 사용하는 경우 시도해 볼 것을 제안합니다 IIS CORS 모듈을 .
모든 유형의 컨트롤러에 대해 구성이 쉽고 작동합니다.

구성 예는 다음과 같습니다.

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

0

나는 DotNet Core MVC를 사용하고 있으며 nuget 패키지, Startup.cs, 속성 및이 장소와 몇 시간 동안 싸운 후 MVC 작업에 간단히 추가했습니다.

Response.Headers.Add("Access-Control-Allow-Origin", "*");

나는 이것이 매우 어수선하다는 것을 알고 있지만, 내가 필요한 전부이며, 헤더를 추가하고 싶은 다른 것은 없습니다. 나는 이것이 다른 누군가를 돕기를 바랍니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.