如何使用 Windows 身份验证在 IIS 上授权 CORS 预检请求

How to authorize CORS preflight request on IIS with Windows Authentication

我在 ASP.net 核心 2(windows 身份验证)上有一个 API,在 angular 上有一个前端。 我进行了 cors 配置以从 SPA angular 查询我的后端,但由于预检而被阻止,因为他没有身份信息而被 IIS 服务器拒绝。

错误信息:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://XXXXXX' is therefore not allowed access. The response had HTTP status code 401.

代码正面:

//MY HEADER
private headers = new Headers({
    'Content-Type': 'application/json', 
    'Access-Control-Allow-Credentials':'true',
    'Access-Control-Allow-Origin':'true'
});

//REQUEST
let options = new RequestOptions({headers:this.headers, withCredentials:true});
return this.http.get(this.tasksUrl,options).map(res=>res.json());

代码侧回:(Startup.cs)

public void ConfigureServices(IServiceCollection services)
{
   services.AddCors();
   services.AddCors(options =>
   {
       options.AddPolicy("AllowSpecificOrigin",
            builder =>
            {
               builder.WithOrigins("http://theURLofTheFront:8080" )
               .AllowAnyMethod()
               .AllowAnyHeader()
               .AllowCredentials();
            });
   });
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        app.UseCors("AllowSpecificOrigin");
        app.UseMvc();
    }

我试试这个:

.

并且我添加了自定义 header 以在 IIS 上指定 'Acces-control-allow-origin',对我不起作用。

这对我不起作用: https://blogs.msdn.microsoft.com/friis/2017/11/24/putting-it-all-together-cors-tutorial/

我无法删除默认授权规则。

我提前谢谢你

预检请求不发送验证信息。因此,也启用匿名身份验证(无需删除 windows 身份验证)。参考

我用 IIS 模块 Cors 解决了我的问题

有几种方法可以做到这一点,其他答案可以在这个类似的问题上找到 -->


CORS 模块

可以使用 CORS Module.
配置 IIS 如此处所示:https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
此处提供更多信息:https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module

The IIS CORS module is designed to handle the CORS preflight requests before other IIS modules handle the same request. The OPTIONS requests are always anonymous, so CORS module provides IIS servers a way to correctly respond to the preflight request even if anonymous authentification needs to be disabled server-wise.

您需要通过 Webconfig 启用 CORS 模块:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <cors enabled="true">
      <add origin="*" allowCredentials="true" />
    </cors>
  </system.webServer>
</configuration>

更精细的控制:

<?xml version="1.0"?>
<configuration>
  <system.webServer>
    <cors enabled="true">
      <add origin="https://readonlyservice.constoso.com" allowCredentials="true">
        <allowMethods>
            <add method="GET" />
            <add method="HEAD" />
        </allowMethods>
        <allowHeaders>
            <add header="content-type" /> 
            <add header="accept" /> 
        </allowHeaders>
      </add>
      <add origin="https://readwriteservice.constoso.com" allowCredentials="true">
        <allowMethods>
            <add method="GET" />
            <add method="HEAD" />
            <add method="POST" />
            <add method="PUT" /> 
            <add method="DELETE" />         
        </allowMethods>
      </add>
    </cors>
  </system.webServer>
</configuration>

重定向选项

您可以重定向所有 OPTIONS 请求以始终提供 OK 状态。 然而,这将颠覆预检请求的整个想法,因此只有在适用于您的情况时才使用它。

在 IIS 中安装 redirect module
将以下重定向添加到您的 Webconfig。

<rewrite>
    <rules>
        <rule name="CORS Preflight Anonymous Authentication" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{REQUEST_METHOD}" pattern="^OPTIONS$" />
            </conditions>
            <action type="CustomResponse" statusCode="200" statusReason="Preflight" statusDescription="Preflight" />
        </rule>
    </rules>
</rewrite>

中间件

或者,可以通过在 IIS 中启用匿名身份验证并在 Net Core API 中创建一个中间件来检查一个人是否经过正确身份验证来实现所需的结果。

中间件:

public AuthorizationMiddleware(RequestDelegate next, ILogger logger)
{
    _next = next;
    _log = logger;
}

public async Task Invoke(HttpContext httpContext)
{
    //Allow OPTIONS requests to be anonymous
    if (httpContext.Request.Method != "OPTIONS" && !httpContext.User.Identity.IsAuthenticated)
    {
        httpContext.Response.StatusCode = 401;
        await httpContext.Response.WriteAsync("Not Authenticated");
    }
    await _next(httpContext);
}