0

我正在创建一个使用 React 构建的应用程序,其中 API 请求将从http://localhost:3000发送到位于https://localhost:5000的 .NET 服务器。这在禁用 Windows 身份验证时有效,但当使用 IIS 启用 Windows 身份验证时,任何请求都会返回 401 未授权。

我做了很多研究,发现我可以通过发送带有 { withCredentials: true } 的 axios 请求来很好地发送 GET 请求。如果我发送一个 POST 请求,这仍然会从服务器返回 401 未经授权,除非我根据这些规范将内容类型设置为 application/x-www-form-urlencoded 来使请求成为“简单请求”:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

当启用 Windows 身份验证时,我需要在 Web 配置中添加什么内容才能使这些请求正常工作吗?

此处对类似问题的回答对我没有帮助:Angular 5: Post-request & windows authentication,因为同时启用了匿名和 Windows 身份验证,将导致对服务器的初始 GET 请求,无法获得 Active目录用户名,使用 Windows 身份验证,因为看起来匿名身份验证优先。

我可以将内容类型设置为 application/x-www-form-urlencoded 来发出 POST 请求,但这似乎是错误的做法。有什么方法可以在服务器上设置一些设置,以便在启用 Windows 身份验证时,位于https://localhost:5000的服务器将接受来自http://localhost:3000且内容类型为 JSON 的任何 API 请求?

4

2 回答 2

2

您需要在服务器上设置CORS 。

这里有一些资源如何在 Web API 2 中做到这一点

同样根据 W3C 规范CORS 预检请求从不包含凭据,因此您可能需要在 IIS 中为 OPTIONS 请求启用匿名

更新:Windows Auth vs OPTIONS 请求

由于我最近遇到了同样的问题,所以这里有一个小的更新。

解决方案 1(我最初链接的) - 添加<allow verbs="OPTIONS" users="*"/>确实不起作用。或者更好地说它“有点工作”,因为它需要在 IIS 中启用匿名身份验证,这是您在使用 Windows Auth 时不想要的

解决方案 2实际上确实有效。关键是里面的代码Application_AuthenticateRequest。同样重要的是它仅在使用集成管道时才有效。它解决了 OPTIONS 请求被 Windows Auth 停止的问题(如果您禁用匿名身份验证,无论您做什么,都会发生这种情况)

一些 MS 员工在这里这里提到的最后一个解决方案是使用 IIS 模块(插件)IIS CORS。这是一个配置参考和简短但有用的介绍

这样做的明显缺点是它需要安装在包括您自己的开发机器在内的每台服务器上。显然没有简单的方法将它安装到 IIS Express 中。幸运的是,“混血程序员”创建了一组 PowerShell 脚本来自动执行此操作。对其进行了测试,它运行良好 - 只是不要忘记 Visual Studio 在解决方案文件夹中创建了主文件的副本applicationHost.config(通常位于MyDocuments\IISExpress\config\文件夹中),.vs\%projectname%\config因此您可能需要为此副本再次运行脚本......

于 2019-12-07T17:44:55.480 回答
0

原来是CORS问题。我发现有趣的是,在启用 Windows 身份验证时,以下两种方式启用 CORS 不起作用:

WebApiConfig.cs

// Web API configuration and services
var cors = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors);

网络配置

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name = "Access-Control-Allow-Credentials" value="true" />
            <add name = "Access-Control-Allow-Headers" value="Origin, Accept, Content-Type, X-Auth-Token" />
            <add name = "Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
            <add name = "Access-Control-Max-Age" value="86400" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

这是我不会从 API 获得 401 未授权返回的唯一方法,即当我通过将 CORS 放入Global.asax.cs文件中以以下方式启用 CORS 时,通过在预检期间返回 200 用于 OPTIONS 请求:

public void Application_BeginRequest(object sender, EventArgs e)
{
    string httpOrigin = Request.Params["HTTP_ORIGIN"];
    if (httpOrigin == null) httpOrigin = "*";
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin);
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token");
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");

    if (Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.StatusCode = 200;
        var httpApplication = sender as HttpApplication;
        httpApplication.CompleteRequest();
    }
}
于 2019-12-09T15:50:07.580 回答