ASP.NET Core 6 MVC:仅使用授权策略在 HttpPost 上出现 cors 错误

问题描述 投票:0回答:1

我已将 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”标头请求的资源。

我已经尝试过:

  1. 编辑
    web.config
    以排除处理来自默认 ASP.NET Core 处理程序的
    OPTIONS
    请求,并删除
    ExtensionlessUrlHandler-Integrated-4.0
  2. 等处理程序
  3. UseCors
    添加到
    Program.cs
  4. 处理
    OPTIONS
    中的所有
    Program.cs
    请求,以便他们收到 200 响应
  5. 检查了我在 Azure 应用程序注册下添加的 Web URI(应该可以工作,因为我可以登录...)
  6. 还有一些我不记得的事情了(但来自 StackOverflow 上与 Cors、应用程序注册等相关的帖子)

但是我删除了上面的许多内容,因为它们似乎不起作用。

我不明白为什么对我的 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(/* ... */);
    }
}

我错过了什么?

c# azure asp.net-core-mvc preflight azure-app-registration
1个回答
0
投票

您应该使用必要的 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

© www.soinside.com 2019 - 2024. All rights reserved.