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

12

我有一个基于ASP.net Core 2的API(使用Windows身份验证),还有一个Angular前端页面。我现在想要配置跨域资源共享(CORS),以便从Angular单页应用(SPA)中查询我的后端服务,但是由于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();
    }

我尝试了这个:CORS 预检请求返回 HTTP 401(需要身份验证)并使用 Windows 身份验证,并在 IIS 中添加自定义标头以指定“Access-control-allow-origin”,但对我不起作用。
这个对我也没用:https://blogs.msdn.microsoft.com/friis/2017/11/24/putting-it-all-together-cors-tutorial/
我无法删除默认的授权规则。
提前感谢您。

我通过IIS模块CORS解决了我的问题。 - FRZ7
2个回答

14

有几种方法可以实现这一点,其他答案可以在此类似的问题上找到--> Angular4 ASP.NET Core 1.2 Windows Authentication CORS for PUT and POST Gives 401


CORS模块

使用CORS模块可以配置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

IIS CORS模块旨在处理CORS预检请求,在其他IIS模块处理相同请求之前。OPTIONS请求始终是匿名的,因此CORS模块为IIS服务器提供了一种正确响应预检请求的方式,即使需要禁用服务器级别的匿名身份验证也是如此。

您需要通过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

您可以将所有的 OPTIONS 请求重定向到始终返回 OK 状态。但是这将破坏预检请求的整个思想,因此只有在适用于您的情况下才使用该选项。

在 IIS 中安装重定向模块
将以下重定向添加到您的 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);
}

似乎无法在我古老的IIS 6.1(Win 2008 R2)服务器上安装IIS模块CORS - 这可能是可以预料的。Web平台安装程序不喜欢这个下载。 - bkwdesign
1
撤回我之前的评论,我最终还是在Win2008 R2上安装成功了,在同一页下方有一个x64链接 - bkwdesign
那个重写规则CORS Preflight匿名认证就是我所需要的。谢谢。 - Amir Khan

-2

启用匿名身份验证而不进行其他更改将允许任何人访问资源,这很可能不是目标。 - SanBen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接