CORS 如何使用 IIS Express VS 调试器和凭据(身份验证)允许预检请求

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

我已启用 CORS,如下

程序.cs

builder.Services.AddCors();

var app = builder.Build();
 
app.UseRouting();

app.UseCors(x => x.AllowAnyMethod().AllowAnyHeader().AllowCredentials().SetIsOriginAllowed(origin => true));
 
app.UseAuthentication();

客户

const axiosClient = axios.create({
   baseURL: configuration.apiUrl,
   headers: { "Content-type": "application/json" },
   withCredentials: true });

服务器(LaunchSettings.json)

 "CustomProfile": {
      "commandName": "IISExpress",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development",
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
      }
    },
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:60737",
      "sslPort": 44358
    }
  }

当我打电话时

// Get records list
axiosClient.get('records').then((res: AxiosResponse) => res.data)

我收到带有数据的状态代码 200,并且用户已在后端进行身份验证。

但是当我打电话时

// Create new record
axiosClient.post('record', createCommand).then((res: AxiosResponse) => res.data)

我收到以下错误消息

从“https://localhost:44358/api/records”访问 XMLHttpRequest 来源 'https://localhost:44414' 已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。

知道可能出了什么问题以及如何解决它吗?

authentication cors iis-express asp.net-core-7.0
1个回答
0
投票

您在服务器端的 CORS 设置似乎基本正确,允许任何来源和凭据。但是,预检请求(当您发出“非简单”请求时,浏览器会自动发送该请求,例如带有 JSON 正文的

POST
请求)似乎失败了。

意味着,

Access-Control-Allow-Origin
标头未在预检响应中发送,这是允许来自不同来源的实际请求所必需的。

来自Lex Li评论

预检请求是匿名的,因此 Windows 身份验证只会阻止所有请求并导致问题。您必须在 IIS 或 IIS Express 上使用 IIS CORS 模块才能正确处理该问题。

您可以在“如何使用 Windows 身份验证在 IIS 上授权 CORS 预检请求”中看到该建议,使用 CORS 模块
您需要通过 Webconfig 启用 CORS 模块:

<configuration>
  <system.webServer>
    <cors enabled="true">
      <add origin="https://localhost:44414" allowCredentials="true">
        <allowHeaders allowAllRequestedHeaders="true"/>
        <allowMethods>
          <add method="GET"/>
          <add method="POST"/>
          <add method="OPTIONS"/>
        </allowMethods>
      </add>
    </cors>
  </system.webServer>
</configuration>

ASP.NET Core 中中间件的顺序会影响它们的行为。并指定允许的来源,而不是允许任何来源。这是防止潜在安全问题的良好做法。

将您的 CORS 设置更改为:

var app = builder.Build();

app.UseCors(x => x
    .WithOrigins("https://localhost:44414")
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials());
    
app.UseRouting();
app.UseAuthentication();

使用浏览器开发人员工具,检查预检(选项)请求和响应,以查看发送和接收的标头。确保响应中包含

Access-Control-Allow-Origin
标头并具有正确的值。


当我添加 web.config 文件时,CORS 元素突出显示为无效,并且网站抛出 HTTP 错误 500.19 - 内部服务器错误。

如果 IIS Express 不支持 CORS 模块,则只能在完整版 IIS 中配置。这可能就是您在尝试将 CORS 配置添加到

web.config
文件时遇到 HTTP 错误 500.19 的原因。
Jonathan Channon 有一篇 2013 年的旧文章“在 IISExpress 中启用 CORS” 可能会有所帮助(当时)

但鉴于此限制,我们可能需要恢复直接在 ASP.NET Core 应用程序中配置 CORS,您已经在

Program.cs
文件中开始执行此操作。
由于您遇到 Windows 身份验证阻止浏览器发出的匿名预检请求的问题,您可以尝试在预检请求期间禁用 Windows 身份验证,然后针对实际请求重新启用它。

确保

Program.cs
中的中间件订购正确。
UseCors
方法应位于
UseAuthentication
UseAuthorization
方法之前。

var app = builder.Build();

app.UseCors(x => x
    .WithOrigins("https://localhost:44414")
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials());

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

考虑到 IIS Express 和 Windows 身份验证的限制,您可能需要在 ASP.NET Core 应用程序中手动处理预检请求。这涉及创建一个中间件来拦截 OPTIONS 请求并在应用 Windows 身份验证之前返回 200 OK 响应。

您可以像这样创建一个中间件:

app.Use((context, next) =>
{
    if (context.Request.Method.Equals("OPTIONS", StringComparison.InvariantCultureIgnoreCase))
    {
        context.Response.StatusCode = (int)HttpStatusCode.OK;
        return Task.CompletedTask;
    }
    return next();
});

将此中间件放在中间件管道的最开始,甚至在

UseCors
中间件之前。

实施这些更改后,通过 Visual Studio 在调试模式下运行应用程序来测试您的设置,并尝试从客户端应用程序发出 OPTIONS、GET 和 POST 请求以验证问题是否已解决。 (不要忘记清除浏览器的缓存或尝试在隐身/私人窗口中以避免测试时出现任何缓存问题。)

通过专注于在 ASP.NET Core 应用程序中正确配置 CORS 并确保预检请求能够成功绕过 Windows 身份验证,您应该能够通过 Visual Studio 使用 IIS Express 开发在您的开发环境中工作的解决方案。

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