web-dev-qa-db-ja.com

Asp.Net WebApi2 AspNet.WebApi.Cors 5.2.3で動作しないCORSを有効にする

http://enable-cors.org/server_aspnet.html の手順に従って、RESTful API(ASP.NET WebAPI2で実装)がクロスオリジンリクエスト(CORS有効)で動作するようにしました。 web.configを変更しない限り機能しません。

WebApi Cors依存関係をインストールしました:

install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api

次に、App_Startに次のようにクラスWebApiConfigがあります。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var corsAttr = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(corsAttr);

        var constraintsResolver = new DefaultInlineConstraintResolver();

        constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint));
        config.MapHttpAttributeRoutes(constraintsResolver); 
        config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
        //config.EnableSystemDiagnosticsTracing(); 
        config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>())); 
        config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>()));
        config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler()); 
    }
}

しかし、その後、アプリケーションを実行し、次のようなFiddlerでリソースを要求します。 http:// localhost:51589/api/v1/persons そして応答では、表示されるはずのHTTPヘッダーが表示されませんといった:

  • Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
  • Access-Control-Allow-Origin: *

ステップがありませんか?コントローラーで次の注釈を試しました。

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

同じ結果、CORSは有効になりません。

ただし、web.configに以下を追加すると(AspNet.WebApi.Cors依存関係をインストールしなくても)動作します:

<system.webServer>

<httpProtocol>
  <!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
  <!--
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="content-Type, accept, Origin, X-Requested-With, Authorization, name" />
    <add name="Access-Control-Allow-Credentials" value="true" />
  </customHeaders>
  -->
</httpProtocol>
<handlers>
  <!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH  GET,HEAD,POST,PUT,DELETE and CORS-->
  <!--

  <remove name="WebDAV" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>

どんな助けも大歓迎です!

ありがとうございました。

67
iberodev

簡略化されたデモプロジェクトを作成しました。

上記のAPI LinkをローカルFiddlerから試して、ヘッダーを確認できます。ここに説明があります。

Global.ascx

これはすべてWebApiConfigを呼び出すだけです。それはコード編成に他なりません。

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    }
}

WebApiConfig.cs

ここでの重要なメソッドはEnableCrossSiteRequestsメソッドです。これはallする必要があります。 EnableCorsAttributeグローバルスコープのCORS属性 です。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
        AddRoutes(config);
    }

    private static void AddRoutes(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "Default",
            routeTemplate: "api/{controller}/"
        );
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(
            origins: "*", 
            headers: "*", 
            methods: "*");
        config.EnableCors(cors);
    }
}

値コントローラー

Getメソッドは、グローバルに適用したEnableCors属性を受け取ります。 Anotherメソッドは、グローバルEnableCorsをオーバーライドします。

public class ValuesController : ApiController
{
    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { 
            "This is a CORS response.", 
            "It works from any Origin." 
        };
    }

    // GET api/values/another
    [HttpGet]
    [EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")]
    public IEnumerable<string> Another()
    {
        return new string[] { 
            "This is a CORS response. ", 
            "It works only from two origins: ",
            "1. www.bigfont.ca ",
            "2. the same Origin." 
        };
    }
}

Web.config

Web.configに特別なものを追加する必要はありません。実際、これはデモのweb.configの外観です-空です。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>

デモ

var url = "https://cors-webapi.azurewebsites.net/api/values"

$.get(url, function(data) {
  console.log("We expect this to succeed.");
  console.log(data);
});

var url = "https://cors-webapi.azurewebsites.net/api/values/another"

$.get(url, function(data) {
  console.log(data);
}).fail(function(xhr, status, text) {
  console.log("We expect this to fail.");
  console.log(status);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
86
Shaun Luttin

いくつかのファイルを変更するだけです。これは私のために動作します。

Global.ascx

public class WebApiApplication : System.Web.HttpApplication {
    protected void Application_Start()
    {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
    } }

WebApiConfig.cs

すべてのリクエストはこのコードを呼び出す必要があります。

public static class WebApiConfig {
    public static void Register(HttpConfiguration config)
    {
        EnableCrossSiteRequests(config);
        AddRoutes(config);
    }

    private static void AddRoutes(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "Default",
            routeTemplate: "api/{controller}/"
        );
    }

    private static void EnableCrossSiteRequests(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute(
            origins: "*", 
            headers: "*", 
            methods: "*");
        config.EnableCors(cors);
    } }

一部のコントローラー

変更するものはありません。

Web.config

web.configにハンドラを追加する必要があります

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

CORSリクエストの場合、最新のブラウザはすべてOPTION動詞で応答し、その後、実際のリクエストが続きます。これは、CORS要求の場合にユーザーに確認を求めるために使用されることになっています。ただし、APIの場合、この検証プロセスをスキップする場合は、Global.asaxに次のスニペットを追加します

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");

                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

ここでは、OPTIONS動詞をチェックしてチェックに合格するだけです。

11
Neeraj

Web.configにカスタムヘッダーを追加したところ、魅力的に機能しました。

設定時-system.webServer:

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

フロントエンドアプリとバックエンドを同じソリューションで使用しています。これが機能するためには、Webサービスプロジェクト(バックエンド)をデフォルトの機能として設定する必要があります。

私はReSTを使用していましたが、他に試したことはありません。

8
Mathter

Web.config CORSにいくつかの変更を加えた後、Web API 2プロジェクトでCORSが突然機能しなくなりました(少なくともプリフライト中のOPTIONSリクエストの場合)。 Web.configに以下のセクションがある必要があるようです。さもないと、(グローバルな)EnableCorsAttributeはOPTIONSリクエストで動作しません。これは、Visual Studioが新しいWeb API 2プロジェクトに追加するセクションとまったく同じであることに注意してください。

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

これらの答えのどれも実際には機能しません。他の人が指摘したように、Corsパッケージは、リクエストにOriginヘッダーがある場合にのみAccess-Control-Allow-Originヘッダーを使用します。しかし、一般的にブラウザはリクエストにOriginヘッダーを追加することはできません。ブラウザーもそれを規制しようとするからです。

Web APIへのクロスサイトリクエストを許可するための迅速で汚れた方法が必要な場合は、カスタムフィルター属性を記述する方がはるかに簡単です。

public class AllowCors : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext == null)
        {
            throw new ArgumentNullException("actionExecutedContext");
        }
        else
        {
            actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin");
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        }
        base.OnActionExecuted(actionExecutedContext);
    }
}

次に、コントローラーアクションで使用します。

[AllowCors]
public IHttpActionResult Get()
{
    return Ok("value");
}

一般にこのセキュリティを保証するつもりはありませんが、web.configでヘッダーを設定するよりもおそらく安全です。なぜなら、この方法では、必要なだけ具体的に適用できるからです。

そしてもちろん、特定の起源、メソッドなどのみを許可するように上記を変更するのは簡単です。

2
Matthew

WEBAPI2:ソリューション。 global.asax.cs:

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

ソリューションエクスプローラーで、api-projectを右クリックします。プロパティウィンドウで'Anonymous Authentication' to Enabled !!!

これが将来誰かを助けることを願っています。

1

CORSをグローバルに有効にする を試みて、この同じ問題が発生しました。しかし、私はそれがわかったdoesが、リクエストにOriginヘッダー値が含まれている場合にのみ動作します。 Originヘッダー値を省略すると、応答にはAccess-Control-Allow-Originが含まれません。

DHC というchromeプラグインを使用して、GETリクエストをテストしました。 Originヘッダーを簡単に追加できました。

1
Rick

Neerajよりも安全で、Matthewよりも簡単であるために、私にとって安全なソリューションはありません。次を追加してください:System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

コントローラーのメソッド内。それは私のために働く。

public IHttpActionResult Get()
{
    System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    return Ok("value");
}
0
puipuix

ほとんどのブラウザが送信するOPTIONSリクエストに問題があるため、この質問を見つけました。私のアプリはOPTIONSリクエストをルーティングし、IoCを使用して多くのオブジェクトを構築し、いくつかはさまざまな理由でこの奇妙なリクエストタイプで例外をスローしていました。

基本的にすべてのOPTIONSリクエストが問題を引き起こしている場合は、無視ルートに入れます:

var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) };
config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);

詳細: OPTIONSリクエストのWeb API処理を停止

0

これが将来誰かを助けることを願っています。私の問題は、グローバルなCORSを有効にするためにOPと同じチュートリアルに従っていたことです。ただし、AccountController.csファイルでアクション固有のCORSルールも設定します。

[EnableCors(origins: "", headers: "*", methods: "*")]

また、Originがnullまたは空の文字列であってはならないというエラーが表示されていました。しかし、すべての場所のGlobal.asax.csファイルでエラーが発生していました。解決策は次のように変更することです。

[EnableCors(origins: "*", headers: "*", methods: "*")]

起源に*がありますか? Global.asax.csファイルでエラーが発生した原因はそれでした。

これが誰かを助けることを願っています。

0
jangooni