ASP.net Core WebAPIでCORSを有効にする方法


190

私がやろうとしていること

Azure Free PlanでホストされているバックエンドASP.Net Core Web APIを持っています(ソースコード:https : //github.com/killerrin/Portfolio-Backend)。

また、そのAPIを使用したいクライアントWebサイトもあります。クライアントアプリケーションは、Azureではホストされませんが、Github Pagesまたは私がアクセスできる別のWebホスティングサービスでホストされます。このため、ドメイン名は整列しません。

これを調べてみると、Web API側でCORSを有効にする必要がありますが、今では数時間にわたってほぼすべてを試してみましたが、機能しません。

クライアントの設定方法 React.jsで記述された単純なクライアント。JqueryでAJAXを介してAPIを呼び出しています。Reactサイトは機能しているので、そうではありません。Jquery API呼び出しは、試行1で確認したとおりに機能します。呼び出しを行う方法を次に示します

    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
    //alert(username + "|" + password + "|" + apiUrl);
    $.ajax({
        url: apiUrl,
        type: "POST",
        data: {
            username: username,
            password: password
        },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var authenticatedUser = JSON.parse(response);
            //alert("Data Loaded: " + authenticatedUser);
            if (onComplete != null) {
                onComplete(authenticatedUser);
            }
        },
        error: function (xhr, status, error) {
            //alert(xhr.responseText);
            if (onComplete != null) {
                onComplete(xhr.responseText);
            }
        }
    });

私が試したこと


試み1-「適切な」方法

https://docs.microsoft.com/en-us/aspnet/core/security/cors

私はMicrosoftのWebサイトでこのチュートリアルに従って、Startup.csでグローバルに有効にする3つのオプションをすべて試し、すべてのコントローラーで設定し、すべてのアクションで試しました。

この方法に従うと、クロスドメインは機能しますが、単一のコントローラーの単一のアクション(AccountControllerへのPOST)でのみ機能します。それ以外の場合、Microsoft.AspNetCore.Corsミドルウェアはヘッダーの設定を拒否します。

Microsoft.AspNetCore.CorsNUGET を使用してインストールしましたが、バージョンは1.1.2

Startup.csで設定する方法は次のとおりです

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Cors
        services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        // Add framework services.
        services.AddMvc();
        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
        });

        ...
        ...
        ...
    }

    // This method gets called by the runtime. Use this method to configure 
    //the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        // Enable Cors
        app.UseCors("MyPolicy");

        //app.UseMvcWithDefaultRoute();
        app.UseMvc();

        ...
        ...
        ...
    }

ご覧のとおり、私は言われたとおりにすべてを行っています。私はMVCの前に両方のCorsを追加しましたが、それがうまくいかないときは[EnableCors("MyPolicy")]、すべてのコントローラーをそのように配置しようとしました

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

試行2-ブルートフォーシング

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

数時間前の試行を試みた後、ヘッダーを手動で設定して、すべての応答でヘッダーを強制的に実行することにより、ブルートフォースにしようと考えました。このチュートリアルに従って、すべての応答に手動でヘッダーを追加する方法を説明しました。

これらは私が追加したヘッダーです

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

これらは私が試した他のヘッダーで失敗しました

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

この方法では、クロスサイトヘッダーが適切に適用され、開発者コンソールとPostmanに表示されます。しかし問題は、Access-Control-Allow-Originチェックに合格している間、ウェブブラウザがヒス音を当てるということです(私は信じています)Access-Control-Allow-Headers述べます415 (Unsupported Media Type)

したがって、ブルートフォースメソッドも機能しません


最後に

誰かがこれを機能させて手を貸すことができましたか、それとも私を正しい方向に向けることができましたか?


編集

したがって、API呼び出しを実行するには、JQueryの使用を停止し、Pure Javascript XMLHttpRequest形式に切り替える必要がありました。

試行1

メソッドをbeforeに置くことMicrosoft.AspNetCore.Corsを除いて、MindingDataの回答に従ってを動作させることができました。Configureapp.UseCorsapp.UseMvc

さらに、options.AllowAnyOrigin()ワイルドカードサポート用のJavascript APIソリューションと組み合わせると、同様に機能し始めました。

試行2

そのため、試行2(ブルートフォーシング)を機能させることAccess-Control-Allow-Originができました。ワイルドカードが機能しないという唯一の例外があるため、それにアクセスできるドメインを手動で設定する必要があります。

このWebAPIをすべての人に広く公開したいので、明らかに理想的ではありませんが、少なくとも別のサイトで機能します。

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
    .AddDefaultSecurePolicy()
    .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
    .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
    .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));

2
415 (Unsupported Media Type)問題については、Content-Typeリクエストヘッダーをに設定しapplication/jsonます。
Technetium 2017

5
そのような説明的な質問を書くために時間を割いてくれてありがとう。
user1007074 2018

1
Postmanを使用してテストしている場合、Originを*またはリクエストヘッダーの何かに設定していることを確認してください。試行#1が機能するはずです。このヘッダーがない場合、Access-Control-Allow-Originは応答ヘッダーで返されません。
tala9999

回答:


239

非常に単純なCORSポリシー(XXXドメインからのすべての要求を許可する)があるので、それほど複雑にする必要はありません。まず次のことを試してください(CORSの非常に基本的な実装)。

CORS nugetパッケージをまだインストールしていない場合はインストールします。

Install-Package Microsoft.AspNetCore.Cors

startup.csのConfigureServicesメソッドで、CORSサービスを追加します。

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

次に、startup.csのConfigureメソッドに以下を追加します。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Make sure you call this before calling app.UseMvc()
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

今それをやってみます。ポリシーは、さまざまなアクション(たとえば、異なるホストまたは異なるヘッダー)に異なるポリシーが必要な場合に使用します。あなたの簡単な例では、あなたは本当にそれを必要としません。この簡単な例から始め、必要に応じて微調整してください。

さらに読む:http : //dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/


3
XMLHttpRequestがandrewgodfroyportfolioapi.azurewebsites.net/api/Authenticationを読み込めません。プリフライト要求への応答がアクセス制御チェックに合格しません:要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン ' localhost:3000 'はアクセスを許可されていません。応答がなかったHTTPステータスコード415
killerrin

7
app.UseCors AFTER `` app.UseMvc() ` を登録すると、これは機能しません。ミドルウェアは登録された順に実行されます
Tseng

24
app.UseMvcの前にapp.UseCorsを使用すると、Configureメソッドで機能するようです。何らかの理由で、順序が重要であるように思われます。
MrClan 2017

1
私にとって、2.0でのCORSの最大の問題は、CORSヘッダーの設定に失敗するだけで、何が問題なのかを通知しないことです。:必要なすべてのヘッダーをポリシーに追加することを忘れないでください。また、CORSミドルウェアが要求処理を停止せず、ログでオリジンが許可されていないことを通知するだけで、私には奇妙なことです。要求をさらに渡します(ミドルウェアの順序は正しい)。
Andrii M4n0w4R 2017年

2
options.DisableHttpsRequirement();これを機能させるには、有効にする必要がありました。https cors設定では適用されていなかったようです。
マイケルブラウン

210
  • ConfigureServices追加 services.AddCors(); services.AddMvc()の前に。

  • UseCorsを追加 Configure

     app.UseCors(builder => builder
         .AllowAnyOrigin()
         .AllowAnyMethod()
         .AllowAnyHeader());   
     app.UseMvc();

重要なのはapp.UseCors、前に追加することapp.UseMvc()です。

MVCパイプラインが制御を取得してリクエストを終了する前にミドルウェアが起動するように、MVCの前にCORS機能を宣言してください。

上記の方法が機能したら、API呼び出しを受け入れるように特定のORIGINを構成し、APIを誰もが利用できるようにしておくことを回避するように変更できます。

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
    {
        builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));

    services.AddMvc();
}

configureメソッドで、作成したポリシーを使用するようCORSに指示します。

app.UseCors("ApiCorsPolicy");
app.UseMvc();

私はこの件についてこのコンパクトな記事を見つけました -https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi


1
これは私にとってはうまくいきます。codeproject.com/Articles/1150023/...
hubert17

17
これは本当に良い「出発点」としてより多くの賛成票を獲得するはずです。コーディングの25年以上の私の経験では、水門を開いて実際に機能することを確認し、必要に応じて開閉する方法を知っておくのは常に素晴らしいことです。
インディジョーンズ

4
ただ、とは対照的に、これを言及するConfigure()ため以内にこちら本当に重要ではありませんConfigureServices()
B12Toaster

さらにリーダーのリンクを使用して、これらの手順でこのエラーを解決しました。これらの変更をどこに配置すればよいかわかりませんでした(APIだと思いました)。リンクにより、APIに配置する必要があることが確認されました。助けてくれてありがとう。私はこのエラーで車輪を完全に回転させていました。
リチャード

1
FYI-CORS仕様では、Access-Control-Allow-Credentialsヘッダーが存在する場合、オリジンを "*"(すべてのオリジン)に設定することは無効であるとも述べています。あなたが使用することはできません意味AllowCredentials()AllowAnyOrigin()上記のように。使用AllowCredentials()するには、を設定する必要がありますWithOrigins()docs.microsoft.com/en-us/aspnet/core/security/...
ニック・デ・ビール

28

私のために働く自分のミドルウェアクラスを作成しました、.netコアミドルウェアクラスに何か問題があると思います

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

そしてstartup.csでこのように使用しました

app.UseCorsMiddleware();

Access-Control-Allow-Originを実行する非常にエレガントな方法。
ArturPoniedziałek17年

これはWebAPIとMVCで動作し、依存関係はありません。ありがとうございます。
ジョー

これについても懐疑的でしたが、うまくいきました。これを達成するためにインターネットで見つけることができる他のすべての方法を基本的に試しましたが、サーバーがアクセスヘッダーで応答しないものは関係ありません。これはうまくいきました。私はaspnetcore 2.1を実行しています。
ジョーダン

クライアントがリクエストでヘッダー「Origin」を送信した場合のみ、corsヘッダーを返す必要があります。元CospMiddlewareでは、次のようになりますif (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
アンドリューPrigorshnev

2
たぶん「.netコアミドルウェアクラスに問題があります」というのは、curlなどでテストするときにヘッダー「Origin」を追加しないためです。ブラウザは、jsコードでリクエストを行うと、このヘッダーを自動的に追加します。
Andrew Prigorshnev

18

私の場合、getリクエストのみがMindingDataの回答に従ってうまく機能します。他のタイプのリクエストについては、次のように記述する必要があります。

app.UseCors(corsPolicyBuilder =>
   corsPolicyBuilder.WithOrigins("http://localhost:3000")
  .AllowAnyMethod()
  .AllowAnyHeader()
);

追加することを忘れないでください .AllowAnyHeader()


AllowAnyHeader()が必要であるというTowhidに同意します。HEADERのリクエストに何か欠落している場合、サーバーはOPTIONSリクエストを受信できます。
Rivon、2017年

.AllowAnyHeader()は私のためにそれをしました、私はプリフライト応答で問題がありました。
takaz

11

user8266077答えさらに詳しく説明するために、私は.NET Core 2.1プレビューでのプリフライトリクエストにOPTIONS応答を提供する必要があることがわかりました。

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

次に、Startup.csでミドルウェアを有効にします。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}

1
私はそのようにミドルウェアを追加することをお勧めします:app.Use<CorsMiddleware>();
Albert221

これらの2つのligneを置き換えることができます:context.Response.StatusCode =(int)HttpStatusCode.OK; await context.Response.WriteAsync(string.Empty); シンプルな:return;
Hayha、

1
@ user8266077の答えの拡張を拡張するには:他の何らかの理由でリクエストが失敗した場合、このミドルウェアは例外をスローし、ヘッダーは設定されないことに注意してください。つまり、フロントエンドでは、まったく異なるものであっても、CORSの問題のように見えます。これを回避するには、例外をキャッチしawait _next(context)、ステータスコードと手動での応答を設定します。また、承認を必要とするreactからのリクエストを行うときにプリフライトリクエストが機能するように、Access-Control-Allow-Headersに「承認」を追加する必要がありました。
Adam

11
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {      
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }

.SetIsOriginAllowed((host)=> true)が解決しました。
JensB

うわー、それで私は他の答えのどれもがわずか3票のこの小さな前に機能することを完全に期待していました。しかし、私はそれぞれを細心の注意を払って試しました...気まぐれであなたのために行きました、そしてそれはうまくいきました ありがとう
ロベルト・トマス

これは、.NET Core 3.1でほとんどすべてを許可するために機能したものです。
JustinHui

10

私はDAYSの間これに苦労していました。

app.UseCors(CORS_POLICY);TOPに移動して、ようやく動作しましたConfigure()

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas

MVCがリクエストを完了する前にヘッダーを適用する必要があるため、> MVCの前にCORS機能を宣言してください。

<=アプリが呼び出さなかったにもかかわらず、一番上UseMVC()に移動UseCors()すると問題が解決しました

また:

  • Microsoft.AspNetCore.Cors以前は、.Net Core 2以前では必須のNuGetパッケージでした。これは自動的に.Net Core 3以降のMicrosoft.AspNetCoreの一部になります。
  • builder.AllowAnyOrigin() そして .AllowCredentials() CORSオプションは、.Net Core 3以降では相互に排他的です。
  • CORSポリシーでは、Angularがでサーバーを呼び出す必要があるようですhttps。.Net CoreサーバーのCORS構成に関係なく、http URLはCORSエラーを発生させるように見えました。たとえばhttp://localhost:52774/api/Contacts、CORSエラーが発生します。URLを単に有効に変更するだけhttps://localhost:44333/api/Contactsです。

追記

私の場合、app.UseCors()上に移動するまでCORSは機能しませんapp.UseEndpoints(endpoints => endpoints.MapControllers())


2
Net Core 3を使用している場合、これが答えになるはずです。私の命を救ってくれてありがとう!
カナダワン

2
「エンドポイントルーティングでは、UseRoutingとUseEndpointsの呼び出し間で実行されるようにCORSミドルウェアを構成する必要があります。構成が正しくないと、ミドルウェアが正しく機能しなくなります。」ここdocs.microsoft.com/en-us/aspnet/core/security/...
マーク・庄屋

「エンドポイントルーティングでは、UseRoutingとUseEndpointsの呼び出し間で実行されるようにCORSミドルウェアを構成する必要があります。構成が正しくないと、ミドルウェアが正しく機能しなくなります。」ここdocs.microsoft.com/en-us/aspnet/core/security/...
マーク・庄屋

7

上記の手順のいずれも役に立たなかったため、問題を解決した記事を読みました。

以下はコードです。

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

そして

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

そして私のアクションメソッドの上に

[EnableCors("CorsPolicy")]

2
これはおそらく悪い考えです。ミドルウェア(app.UseCors())を[EnableCors()]同じアプリケーションに混在させないでください。どちらか一方を使用する必要があります-両方ではありません:docs.microsoft.com/en-us/aspnet/core/security/…Use the [EnableCors] attribute or middleware, not both in the same app.
FoggyDay

4

jQuery.support.cors = true;Ajax呼び出しの前に追加してみてください

APIへの送信データが不安定である可能性もあります。

次のJSON関数を追加してみてください

        var JSON = JSON || {};

    // implement JSON.stringify serialization
    JSON.stringify = JSON.stringify || function (obj) {

        var t = typeof (obj);
        if (t != "object" || obj === null) {

            // simple data type
            if (t == "string") obj = '"' + obj + '"';
            return String(obj);

        }
        else {

            // recurse array or object
            var n, v, json = [], arr = (obj && obj.constructor == Array);

            for (n in obj) {
                v = obj[n]; t = typeof (v);

                if (t == "string") v = '"' + v + '"';
                else if (t == "object" && v !== null) v = JSON.stringify(v);

                json.push((arr ? "" : '"' + n + '":') + String(v));
            }

            return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
        }
    };

    // implement JSON.parse de-serialization
    JSON.parse = JSON.parse || function (str) {
        if (str === "") str = '""';
        eval("var p=" + str + ";");
        return p;
    };

次に、データで:オブジェクトを次のように変更します

    data: JSON.stringify({
        username: username,
        password: password
    }),

ご協力いただきありがとうございます。全員の回答を組み合わせた後、最終的に解決策を理解するために回答の一部を確実に利用した
killerrin

4

最も簡単なソリューションは追加です

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseCors(options => options.AllowAnyOrigin());

        app.UseHttpsRedirection();
        app.UseMvc();
    }

Startup.csに。


3

独自のCORSミドルウェアを使用する場合は、オリジンヘッダーをチェックして、それが本当にCORSリクエストであることを確認する必要があると思います。

 public class CorsMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMemoryCache _cache;
    private readonly ILogger<CorsMiddleware> _logger;

    public CorsMiddleware(RequestDelegate next, IMemoryCache cache, ILogger<CorsMiddleware> logger)
    {
        _next = next;
        _cache = cache;
        _logger = logger;
    }
    public async Task InvokeAsync(HttpContext context, IAdministrationApi adminApi)
    {
        if (context.Request.Headers.ContainsKey(CorsConstants.Origin) || context.Request.Headers.ContainsKey("origin"))
        {
            if (!context.Request.Headers.TryGetValue(CorsConstants.Origin, out var origin))
            {
                context.Request.Headers.TryGetValue("origin", out origin);
            }

            bool isAllowed;
            // Getting origin from DB to check with one from request and save it in cache 
            var result = _cache.GetOrCreateAsync(origin, async cacheEntry => await adminApi.DoesExistAsync(origin));
            isAllowed = result.Result.Result;

            if (isAllowed)
            {
                context.Response.Headers.Add(CorsConstants.AccessControlAllowOrigin, origin);
                context.Response.Headers.Add(
                    CorsConstants.AccessControlAllowHeaders,
                    $"{HeaderNames.Authorization}, {HeaderNames.ContentType}, {HeaderNames.AcceptLanguage}, {HeaderNames.Accept}");
                context.Response.Headers.Add(CorsConstants.AccessControlAllowMethods, "POST, GET, PUT, PATCH, DELETE, OPTIONS");

                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("CORS with origin {Origin} was handled successfully", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                await _next(context);
            }
            else
            {
                if (context.Request.Method == "OPTIONS")
                {
                    _logger.LogInformation("Preflight CORS request with origin {Origin} was declined", origin);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    return;
                }

                _logger.LogInformation("Simple CORS request with origin {Origin} was declined", origin);
                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                return;
            }
        }

        await _next(context);
    }

どうもありがとうございました。Access-Control-Allow-Originヘッダーがサーバーによって発行されなかった理由を私は自問しました。実際、私はOriginヘッダーなしでPostman経由でリクエストを送信しました。これは私の日を救った!(または、少なくとも私の前夜;))
Paul Kertscher

2

MindingDataの回答でのあなたのコメントに基づくと、それはCORSとは何の関係もなく、うまく機能しています。

コントローラアクションが間違ったデータを返しています。HttpCode 415は、「サポートされていないメディアタイプ」を意味します。これは、間違った形式をコントローラーに渡す(つまり、jsonのみを受け入れるコントローラーにXMLを渡す)か、間違った型を返す(xmlのみを返すように宣言されているコントローラーでXmlを返す)場合に発生します。

後で1つ[Produces("...")]、アクションの属性の存在を確認します


ご協力いただきありがとうございます。新しいソリューションを試して、jsonが送信されるのを試してみたところ、文字
列化し

2

私にとっては、使用していたコードとは何の関係もありませんでした。Azureの場合は、サイドメニューの[CORS]エントリでApp Serviceの設定に移動する必要がありました。そこで、リクエスト元のドメインを追加する必要がありました。私がそれを手に入れたら、すべてが魔法でした。


2

launchSettings.jsonのiisSettingsで、anonymousAuthenticationをtrueに設定します。

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:4200/",
      "sslPort": 0
    }
  }

次に、Startup.csのConfigureServicesの下で、services.AddMvcの前に以下を追加します。

services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
    builder
        .AllowAnyOrigin()
        .WithHeaders(HeaderNames.AccessControlAllowHeaders, "Content-Type")
        .AllowAnyMethod()
        .AllowCredentials();
}));

そして、configureメソッドで、app.UseMvc()の前に以下を追加します。

app.UseCors("ApiCorsPolicy");

これでうまくいきました。最初にプロジェクトをWindows認証用に設定しましたが、その後匿名に変更する必要がありました。CORSを正しく構成しましたが、launchSettings.jsonのこの設定が原因でした。投稿していただきありがとうございます。
HaRoLD

2

私は.NET CORE 3.1を使用していて、コードが実際に機能し始めたのにデバッグ環境が壊れていることに気付いたとき、これを使って壁に頭をぶつけてきました。トラブルシューティングをしようとしている場合の2つのヒント問題:

  1. ASP.NETミドルウェアを使用して応答ヘッダーをログに記録しようとしている場合、「Access-Control-Allow-Origin」ヘッダーがあっても表示されません。方法はわかりませんが、パイプラインの外に追加されるようです(結局、それを表示するにはWiresharkを使用する必要がありました)。

  2. .NET COREは、リクエストに「Origin」ヘッダーがない限り、「Access-Control-Allow-Origin」を応答で送信しません。Postmanはこれを自動的に設定しないので、自分で追加する必要があります。


2

私の場合、UserRoutingの前にUseCorsで修正しました。


dotnet core 2.2から3.1にアップグレードしたとき、私はこれに似たものに遭遇しました。app.UseCors()をapp.UseRouting()の上に移動する必要がありました。この答えは私を正しい方向に向けました。
Brandonm

1

.NET Core 3.1

私のために働いた、そしてドキュメントがそれをするように言う方法:

スタートアップクラス:

readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; 

ConfigureServices()メソッドで:

    services.AddCors(options =>
    {
        options.AddPolicy(MyAllowSpecificOrigins,
        builder =>
        {
            builder.WithOrigins("http://example.com",
                                "http://www.contoso.com");
        });
    });

Configure()メソッドで:

    app.UseCors(MyAllowSpecificOrigins);  

https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1


0

上記のMindingDataの回答が機能するようになりましたが、Microsoft.AspNetCore.CorsではなくMicrosoft.AspNet.Corsを使用する必要がありました。Visual Studio 2019で.NetCore WebアプリケーションAPIプロジェクトを使用しています


2
注:ASP.Net CorアプリケーションでMicrosoft.AspNet.Corsを使用しないでください。.Net Core 3.0以降を使用している場合は、CORSのNuGetパッケージをインポートする必要はありません。.Net Core 2.3以下を使用している場合は、NuGetの適切なバージョンのMicrosoft.AspNet.Corsが必要です。
FoggyDay、

0

Microsoft.AspNetCore.Cors

組み込み機能を使用してCORSを実行できますが、OPTIONSリクエストは処理しません。これまでの最善の回避策は、前の投稿で提案されているように新しいミドルウェアを作成することです。次の投稿で正しいとマークされた回答を確認してください:

.NET Core Web APIでCORSのOPTIONSヘッダーを有効にする


0

それを行うためのシンプルで簡単な方法。

  1. パッケージをインストールする

Install-Package Microsoft.AspNetCore.Cors

  1. 以下のコードをstartup.csファイルに入れます

app.UseCors(options => options.AllowAnyOrigin());


0

これが私のコードです:)

  app.Use((ctx, next) =>
        {
            ctx.Response.Headers.Add("Access-Control-Allow-Origin", ctx.Request.Headers["Origin"]);
            ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            ctx.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            ctx.Response.Headers.Add("Access-Control-Allow-Headers", "AccessToken,Content-Type");
            ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
            if (ctx.Request.Method.ToLower() == "options")
            {
                ctx.Response.StatusCode = 204;

                return Task.CompletedTask;
            }
            return next();
        });

0

これが私がこれをした方法です。

一部の回答では、コントローラーを設定app.UserCors("xxxPloicy")して配置[EnableCors("xxxPloicy")]しているようです。両方を行う必要はありません。

手順は次のとおりです。

ConfigureServices内のStartup.csに次のコードを追加します。

    services.AddCors(c=>c.AddPolicy("xxxPolicy",builder => {
        builder.AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    }));

プロジェクト全体に適用する場合は、Startup.csのConfigureメソッドに次のコードを追加します。

app.UseCors("xxxPolicy");

または

特定のコントローラーに追加する場合は、以下に示すようにenable corsコードを追加します。

[EnableCors("xxxPolicy")]
[Route("api/[controller]")]
[ApiController]
public class TutorialController : ControllerBase {}

詳しくはこちらをご覧ください


0

CORSヘッダーを設定するには、カスタムのアクション/コントローラー属性を使用します。

例:

public class AllowMyRequestsAttribute : ControllerAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // check origin
        var origin = context.HttpContext.Request.Headers["origin"].FirstOrDefault();
        if (origin == someValidOrigin)
        {
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", origin);
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
            context.HttpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*");
            // Add whatever CORS Headers you need.
        }
    }

    public void OnActionExecuting(ActionExecutingContext context)
    {
        // empty
    }
}

次に、Web APIコントローラー/アクションで:

[ApiController]
[AllowMyRequests]
public class MyController : ApiController
{
    [HttpGet]
    public ActionResult<string> Get()
    {
        return "Hello World";
    }
}

0

ここで回答を追加するために、を使用しapp.UseHttpsRedirection()ていてSSLポートではない場合は、これをコメント化することを検討してください。


0

クライアントとしてblazor webassembly、バックエンドとしてasp.net web apiコアを使用していて、corsの問題もありました。

私はこれらのコードで解決策を見つけました:

私のASP.NetコアWeb API Startup.cs ConfigureServicesおよびConfigureメソッドの最初の行は次のようになります。

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
   {
        builder.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader();
    }));

 //other code below...
}

そして私のConfigureメソッド:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCors(
        options =>   options.WithOrigins("http://example.com").AllowAnyMethod().AllowAnyHeader()
            );
 //other code below...
}

http://example.comクライアントドメインまたはIPアドレスで変更する


-1
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddJsonOptions(options => {
                    var resolver = options.SerializerSettings.ContractResolver;
                    if (resolver != null)
                        (resolver as DefaultContractResolver).NamingStrategy = null;
                });

            services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DevConnection"))); //Dependency Injection
            // options => options.UseSqlServer() Lamda Expression

            services.AddCors(options =>
            {
                options.AddPolicy(MyAllowSpecificOrigins,
                    builder =>
                    {
                        builder.WithOrigins("http://localhost:4200").AllowAnyHeader()
                                .AllowAnyMethod(); ;
                    });
            });

コードの説明と他の回答との違いを含めるために、回答を編集してください。これにより、投稿がより便利になり、投票される可能性が高くなります:)
Das_Geek
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.