私のasp.netコアWeb APIで、 MSドキュメント の記事に従ってCorsを構成しました。 Web APIアプリはWindows認証を使用しています(匿名認証は有効になっていません)。 Corのポリシーが作成され、ミドルウェアが以下のようにstartup.cs
に追加されます
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddMvc().AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//Enable CORS policy
app.UseCors("CorsPolicy");
app.UseMvc();
}
コントローラレベルごとのポリシーも適用
[EnableCors("CorsPolicy"), Route("api/[controller]")]
public class LocationController : BaseController<Location>
{
//code
}
オプションのリクエストが不正になっています。リクエストとレスポンスは次のようになります
私は同様の質問を見て、ほとんどすべての解決策を試しましたが、オプション要求はまだ失敗しています。
このスレッドを読むことをお勧めします: https://github.com/aspnet/CORS/issues/6 。匿名とNTLMを組み合わせて、CORSプリフライトが拒否されないようにすることができます(ウィンドウの資格情報が含まれていないため)。 IISミドルウェアに到達する前にNTLM認証を処理するため、これはおそらくIISことです。匿名のCORのプリフライトチェックを許可する必要がある場合があります。
1)LaunchSettings.jsonファイルでAllow Windowsと匿名認証フラグをtrueに設定します。
匿名認証:飛行前のオプション要求を許可するために必要です。
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": true,
"iis":
...
}
2)サービスメソッドの構成でCorsポリシーを追加します。
public void ConfigureServices(IServiceCollection services)
{
...
services.AddCors(options =>
{
options.AddPolicy("MyCustomCorsPolicyName",
builder => builder.WithOrigins("http://YourDomainName/")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
:CORSミドルウェアをWebアプリケーションパイプラインに追加して、クロスドメインリクエストを許可します。
public void Configure(IApplicationBuilder app)
{
....
app.UseCors("MyCustomCorsPolicyName");
app.UseMvc();
}
4)承認属性をコントローラーの上に追加して強制し、クライアントが資格情報を送信する
[Authorize]
public class MyAPIController : ControllerBase
{
...
}
5)JQueryまたは使用しているクライアントでは、withCredentialsプロパティフラグをtrueに設定します
$.ajax({
type: "POST",
datatype: "json",
url: "YourApiUrl",
xhrFields: {
withCredentials: true
}
これは、.netコア2.2、IIS Express with Windows Authentication)を使用する開発環境で私にとってはうまくいきました。
資格情報を渡すか、リクエストと一緒にしたいようです。
資格情報の追加/ユーザー資格情報の許可については このリンク を確認してください。
クロスオリジン認証情報を許可するときは注意してください。別のドメインのWebサイトは、ユーザーの知らないうちにユーザーの代わりにログインユーザーの資格情報をアプリに送信できます。 CORS仕様では、Access-Control-Allow-Credentialsヘッダーが存在する場合、オリジンを "*"(すべてのオリジン)に設定することは無効であるとも述べています。
これは CORSが有効ですが、JSONのPOST時にプリフライトの応答に無効なHTTPステータスコード404が含まれます と私に機能するソリューションを提供しました(POSTリクエストで401エラーが発生しました)また、NTLMとネゴシエートの両方を構成しないでください( ネゴシエートV/s NTLM )。
数時間後にそれを理解した後、完全なソリューション(フロントエンドからバックエンド)を次に示します。
私の問題:Web APIでWindows認証を有効にすると、reactアプリから.NET Core 3.1 Web APIへの呼び出しをフェッチできず、CORSがおかしくなりました。匿名認証では機能しましたが、Windows認証が有効になっている場合は機能しませんでした。
1.launchSettings.json
これは開発環境でのみ使用されます。本番サーバーのIIS)でもWindows認証が有効になっていることを確認してください。
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:58747",
"sslPort": 0
}
},
{... more settings if any}
}
2.Startup.cs:
CORSポリシーはここで有効になります。ここでは、メソッドの順序が重要です。また、web.configでこれらを設定する必要はありません。
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", //give it the name you want
builder =>
{
builder.WithOrigins( "http://localhost:3000", //dev site
"production web site"
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//database services here
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// global policy same name as in the ConfigureServices()
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
.Controller(s):
using Microsoft.AspNetCore.Cors;
... your other usings
namespace ProjectTest.Controllers
{
[ApiController]
[EnableCors("CorsPolicy")] //THIS HERE needs to be the same name as set in your startup.cs
[Route("[controller]")]
public class FooController:Controller
{
[HttpGet("getTest")]
public JsonResult GetTest()
{
return Json("bar");
}
}
}
4.Reactコンポーネントのフェッチ呼び出しの例:
「クレデンシャル: 'include'」が秘密です
await fetch('http://localhost:3000/Foo/getTest', {
method: 'GET',
credentials: 'include'
}).then(resp => resp.json());
IIS CORS Moduleを使用すると問題が見事に解決されました。以下のURLは参照用です。
Windows認証の使用これはCORSモジュールによって解決される唯一のシナリオではありませんが、呼び出すことを保証するのに十分重要でした。以前は、Windows認証を使用するアプリケーションにクロスドメインリクエストを送信しようとすると、ブラウザがプリフライトリクエストで認証情報を送信しなかったため、プリフライトリクエストは失敗しました。アプリケーションで匿名認証を有効にせずにこれを回避する方法はありませんでした。 CORSモジュールは認証の前に起動するため、アプリケーションのセキュリティモデルに妥協することなく、プリフライトリクエストを処理できます。これは、web.configの例です。
https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
サンプルコード:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- To customize the asp.net core module uncomment and edit the following section.
For more info see https://go.Microsoft.com/fwlink/?linkid=838655 -->
<system.web>
<authentication mode="Windows"/>
</system.web>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add Origin="http://localhost:60096" allowCredentials="true" >
<allowHeaders allowAllRequestedHeaders="true">
<add header="Header1" />
</allowHeaders>
</add>
</cors>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Project.Api.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>