1. ホーム
  2. c#

[解決済み】ASP.net Core WebAPIでCORSを有効にする方法

2022-04-19 08:11:40

質問

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

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

また、そのAPIを利用させたいクライアントサイトもあります。クライアントアプリケーションはAzure上ではなく、Github Pagesや私がアクセスできる他のウェブホスティングサービス上でホストされる予定です。このため、ドメイン名は一致しません。

これを調べると、Web API 側で CORS を有効にする必要がありますが、数時間前からあらゆることを試してみましたが、うまくいきません。

クライアントのセットアップ方法 React.jsで書かれたシンプルなクライアントです。JqueryでAJAXを通してAPIを呼び出しています。Reactのサイトは動作するので、それではないことは分かっています。JqueryのAPI呼び出しは、Attempt 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

マイクロソフトのウェブサイトにあるこのチュートリアルに忠実に従いました。Startup.csでグローバルに有効にする、すべてのコントローラで設定する、すべてのアクションで試すという3つのオプションすべてを試してみました。

この方法に従うと、クロスドメインは動作しますが、1つのコントローラ上の1つのアクション(AccountControllerへのPOST)でのみ動作します。それ以外のものについては Microsoft.AspNetCore.Cors ミドルウェアがヘッダを設定することを拒否します。

をインストールしました。 Microsoft.AspNetCore.Cors をNUGET経由で購入し、バージョンは 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();

        ...
        ...
        ...
    }

ご覧のように、私は言われたとおりにすべてやっています。2回とも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")

この方法で、Cross Site Headersは適切に適用され、開発者コンソールとPostmanに表示されるようになりました。しかし、問題なのは Access-Control-Allow-Origin のチェックで、ウェブブラウザがヒスってしまうのです。 Access-Control-Allow-Headers 記載 415 (Unsupported Media Type)

だから、ブルートフォース方式もうまくいかないんだ


最後に

どなたか、これを動作させた方、手を貸していただける方、または正しい方向性を示していただける方はいらっしゃいますか?


EDIT

そのため、APIコールを通過させるために、JQueryの使用をやめ、Pure Javascriptに変更する必要がありました。 XMLHttpRequest の形式を使用します。

試み1

なんとか Microsoft.AspNetCore.Cors を除いて、MindingDataの回答に従って動作させることができます。 Configure を置くメソッド。 app.UseCors の前に app.UseMvc .

また、Javascript API Solutionと混在させた場合 options.AllowAnyOrigin() も動作するようになりました。

試み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"));

解決方法は?

非常にシンプルな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/