我已将 ASP.NET Core 6 MVC 应用程序添加到 Azure“应用程序注册”,我可以使用 Microsoft WebUI 登录并执行
GET
请求来获取例如我的观点。
该应用程序托管在 IIS 8.5 上。
我还在我的 Azure 应用程序注册面板中定义了一些应用程序角色。 当我单击发送
POST
请求的按钮时,会发送预检请求,并且我看到以下错误:
访问“https://login.microsoftonline.com/[omissed]/oauth2/v2.0/authorize?client_id=[omissed]&redirect_uri=https%3A%2F%2F[omissed]%2Fsignin-oidc&response_type=” id_token&scope=openid%20profile&response_mode=form_post&[省略] 来自原点“[省略]”已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:不存在“Access-Control-Allow-Origin”标头请求的资源。
我已经尝试过:
web.config
以排除处理来自默认 ASP.NET Core 处理程序的 OPTIONS
请求,并删除 ExtensionlessUrlHandler-Integrated-4.0
UseCors
添加到 Program.cs
OPTIONS
中的所有 Program.cs
请求,以便他们收到 200 响应但是我删除了上面的许多内容,因为它们似乎不起作用。
我不明白为什么对我的 MVC 控制器的
GET
请求没有问题,而 POST
请求失败(因为发送了预检请求并且讨厌我,而在 GET
请求之前没有发送预检请求)。
此外,这里不涉及 SPA 应用程序,只是普通的 MVC,其视图引用普通的 js 文件(包含一些对 POST 的 fetch 调用)。
Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton... // adding my services like db repository etc.
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
builder.Services
.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("Admin", policy => policy.RequireClaim("roles", "Admin"));
options.AddPolicy("Purchaser", policy => policy.RequireClaim("roles", "Purchaser", "Admin"));
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.AddMicrosoftIdentityUI();
var app = builder.Build();
//...
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
// app.MapAreaControllerRoute and stuff
app.Run();
web.config
:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="GET,POST,PUT,PATCH,DELETE" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"/>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"/>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="WebDav"/>
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0"/>
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
<aspNetCore processPath="dotnet" arguments=".\TaskBridgePortal.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"/>
</system.webServer>
</location>
<system.webServer>
<httpProtocol>
<customHeaders>
<!--add name="Access-Control-Allow-Methods" value="*" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" /-->
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
控制器示例:
[Authorize(Policy = "Orders")]
[Area/*..*/]
public class ReportController : Controller
{
public ReportController(/* ... */)
{
// ...
}
[HttpPost] // fails
public async Task<IActionResult> DownloadReportAsync([FromBody] DownloadReportRequest request)
{
// ...
}
public async Task<IActionResult> ReportAsync(bool returnView = true) // doesn't fail
{
//...
return View(/* ... */);
}
}
我错过了什么?
您应该使用必要的 URL 注册您的 CORS(对于很多 URL,请使用“*”)
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://example.com");
});
});
app.UseCors(MyAllowSpecificOrigins);
此外,还可以为静态文件注册CORS
builder.Services.Configure<StaticFileOptions>(options =>
{
options.OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append("Access-Control-Allow-Origin", "http://example.com");
};
});
您可以在下面找到更多信息:
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0