[解決済み】ASP.net Core WebAPIでCORSを有効にする方法
質問
私がやろうとしていること
私は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/
関連
-
[解決済み] Access-Control-Allow-Originヘッダーはどのように機能するのですか?
-
[解決済み] enumを列挙するには
-
[解決済み] intをenumにキャストするにはどうすればよいですか?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] REST APIからデータを取得しようとしたときに、要求されたリソースに'Access-Control-Allow-Origin'ヘッダーが存在しない。
-
[解決済み] プリフライト要求に対する応答がアクセス制御チェックを通過しない
-
[解決済み] CORSです。資格情報フラグが true の場合、Access-Control-Allow-Origin でワイルドカードを使用できない。
-
[解決済み】http://localhost CORS originが機能しないのはなぜですか?
-
[解決済み] AngularJsでCORSを有効にする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】「namespace」なのに「type」のように使われる。
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する