50

我正在尝试在我的 WebAPI 项目中启用 CORS 支持,如果我启用匿名身份验证,那么一切正常,但是在 Windows Auth +禁用匿名身份验证的情况下,发送的 OPTIONS 请求总是返回 401 未经授权的响应。请求它的站点位于 DOMAIN 上,因此应该能够拨打电话,有没有办法在不禁用 Windows 身份验证的情况下解决这个问题?

4

14 回答 14

42

You can allow only OPTIONS verb for anonymous users.

<system.web>
  <authentication mode="Windows" />
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
      <deny users="?" />
  </authorization>
</system.web>

According W3C specifications, browser excludes user credentials from CORS preflight: https://dvcs.w3.org/hg/cors/raw-file/tip/Overview.html#preflight-request

于 2014-09-15T09:09:40.503 回答
26

Several years later, but through the answer from @dariusriggins and @lex-li I have managed to add the following code to my Global.asax:

    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();
        }
    }

the httpOrigin is actually looked up in a list of allowed hosts but that just complicated things. This means that all other requests are validated but options just returns.

Thanks for this question, I would have been lost without it!

于 2015-09-02T10:56:56.373 回答
15

来自女士:

如果您禁用匿名身份验证,IIS 会根据设计向任何请求返回 401。如果他们启用了 Windows 身份验证,则在这种情况下的 401 响应将具有 WWW-Authenticate 标头以允许客户端启动身份验证握手。那么问题就变成了客户正在使用的客户端是否可以进行 Windows 身份验证。

最后,似乎可能存在一个潜在的问题,即是否可以配置一个 URL,以便允许一个动词(在本例中为 OPTIONS)匿名访问,但需要对其他动词进行 Windows 身份验证。IIS 通过简单的配置不支持这一点。通过启用匿名和 Windows 身份验证,在拒绝匿名用户访问的内容上设置 ACL,然后为相关 URL 配置处理程序映射,使其不会验证是否存在与 URL 关联的文件。但是要确认这一点需要一些时间。

于 2012-05-30T16:25:23.500 回答
5

解决此问题的最简单方法是使用条件 request_method = ^OPTIONS$ 创建重写规则。然后将操作设置为自定义响应,将其设置为 200 OK。然后所有选项请求将响应 200 而不是 401。这将解决 CORS 问题。

当然,您仍然需要确保您拥有正确的跨源请求标头。

当启用集成身份验证时,这将停止以 401 响应的选项请求(没有任何凭据)。

于 2016-01-21T09:56:53.740 回答
4

接受的答案是正确的,但是我在一段时间内使用“带有 iisnode 和 npm cors 模块的节点”设置对 rest api 进行故障排除,并且对只为所有用户启用匿名身份验证感到不舒服。由于它是一个节点应用程序,system.web 标签并没有做太多的事情。我最终在 web.config 中添加了以下内容:

<system.webServer>
<security>
  <requestFiltering>
    <hiddenSegments>
      <add segment="node_modules" />
    </hiddenSegments>
  </requestFiltering>
  <authorization>
    <add accessType="Allow" verbs="OPTIONS" users="?" />
    <add accessType="Deny" verbs="GET, PUT, POST, DELETE" users="?" />
  </authorization>
</security>
</system.webServer>
于 2016-03-18T09:40:16.983 回答
4

相关问题:IIS 劫持 CORS Preflight OPTIONS 请求

合并来自多个地方的答案的信息。如果您需要在 Intranet 上使用 Windows 身份验证在 ASP.net 页面方法上启用 CORS,这似乎可行。没有对 的更改web.config,这是行不通的。

您需要将此添加到Global.asax

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        string httpOrigin = HttpContext.Current.Request.Params["HTTP_ORIGIN"] ?? HttpContext.Current.Request.Params["ORIGIN"] ?? "*";
        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 (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.StatusCode = 200;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

而这web.config

 <system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." 
           verb="*" type="System.Web.Handlers.TransferRequestHandler" 
           preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
于 2019-02-05T23:20:05.297 回答
4

扩展@dariusriggins 提供的答案。查看这篇文章:微软 | 开发人员:将所有内容放在一起 – CORS 教程

对于 IIS 配置:

授权规则

授权规则

授权阶段(或授权事件),我们需要确保只允许来自 CORS 预检的匿名请求,并要求所有其他传入请求都提供身份验证凭据。我们可以通过授权规则来实现这一点。授予所有用户访问站点的默认授权规则已经存在,并且默认由 IIS 提供。我们将首先修改此规则以仅允许匿名用户发送使用 OPTIONS http 动词的请求。以下是 IIS 中此授权规则的目标配置:

编辑授权规则

编辑授权规则

于 2019-08-16T16:43:15.380 回答
3

由于IE 10 和 11中的错误,我今天遇到了同样的问题,我使用的是 ServiceStack 而不是 WebApi,但该方法也适用于您。

  1. 在 IIS 网站上启用 Windows 集成和匿名身份验证。
  2. 在 ServiceStack Pipeline 上有一系列过滤器,
    • 为了处理 Cors 和 OPTIONS 请求,在 Options 请求中,我添加了必要的标头并结束请求,
    • 用于检查的过滤器包括 HttpRequest 是否已通过身份验证?,
    • 等过滤器,

通过所有过滤器后,它执行服务。

CorsFeature.cs

验证过滤器

在我的 AppHost 中,

appHost.Plugins.Add(new CorsFeature());

appHost.RequestFilters.Add(AuthenticateFilter.Authenticate);

除了添加标头之外,我还修改了 CorsFeature 以处理 OptionsRequest,Authenticate Filter 以检查经过身份验证的请求!

于 2014-05-14T19:11:56.603 回答
2

对我有用的(使用 AngularJS 或 JQuery 时)是将 withCredentials:true 添加到客户端的每个请求中:

$http.get("http://localhost:88/api/tests", {withCredentials :true})

并在服务器上启用 CORS,这是使用 nuget 中的 Microsoft.Owin.Cors 完成的,并将其添加到 Startup 中,如下所示:

public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

参考:

于 2015-12-23T14:43:36.710 回答
1

我知道这是一个老问题,有几个可能的解决方案(以及更多问题),但万一其他人遇到这个问题,IIS CORS 1.0 于 17 年 11 月可用:

https://blogs.iis.net/iisteam/introducing-iis-cors-1-0

https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference

您可以通过 IIS Windows 平台安装程序 (WPI) 下载它。这应该可以解决您的许多 CORS 身份验证问题。享受!

于 2018-08-30T20:20:41.307 回答
1

这个 IIS 扩展(IIS CORS 模块)帮助我解决了对启用了 Windows 身份验证的 IIS 托管应用程序的 401-未经授权的预检请求。安装此模块后,我执行了 IISRESET 并在我的 Web 应用程序的 Web.config 文件中添加了以下内容:

<configuration>
    <configSections>
        <!-- ... (configSections must be the first element!) -->
    </configSections>
    <system.webServer>
        <cors enabled="true">
            <add origin="http://localhost:3000" allowCredentials="true" maxAge="120">
                <allowHeaders allowAllRequestedHeaders="true"/>
                <!-- Added 'allowMethods' just in case. -->
                <allowMethods>
                    <add method="HEAD"/>
                    <add method="GET"/>
                    <add method="POST"/>
                    <add method="PUT"/>
                    <add method="DELETE"/>
                    <add method="OPTIONS"/>
                </allowMethods>
            </add>
        </cors>
    </system.webServer>
</configuration>

您可以在此处找到有关如何配置 IIS CORS 模块的更多信息:IIS CORS 模块 入门

于 2021-04-04T09:56:31.763 回答
1

我正在使用 Web API 和 OWIN,我尝试了所有建议的解决方案,但唯一有效的是以下

//use it in your startup class
app.Use((context, next) =>
{
    if (context.Request.Headers.Any(k => k.Key.Contains("Origin")) && context.Request.Method == "OPTIONS")
    {
        context.Response.StatusCode = 200;
        context.Response.Headers.Add("Access-Control-Allow-Origin", new string[1] { "ALLOWED_ORIGIN" });
        context.Response.Headers.Add("Access-Control-Allow-Headers", new string[4] { "Origin", "X-Requested-With", "Content-Type", "Accept" });
        context.Response.Headers.Add("Access-Control-Allow-Methods", new string[5] { "GET", "POST", "PUT", "DELETE", "OPTIONS" });
        context.Response.Headers.Add("Access-Control-Allow-Credentials", new string[1] { "true" });

        return context.Response.WriteAsync("");
    }

    return next.Invoke();
});

//this is important! Without it, it didn't work (probably because the middleware was too late)
app.UseStageMarker(PipelineStage.Authenticate);

您需要将此代码插入您的 OWIN 启动类之一中的某个位置。打电话很重要,app.UseStageMarker(PipelineStage.Authenticate)否则预检检查失败。UseStageMarker 的更多信息-> https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-middleware-in-the-iis-integrated-pipeline

您需要明确定义允许的标头也很重要。*如果您用作占位符,它将失败。

也许它可以帮助某人。

于 2017-04-19T12:10:00.653 回答
0
  • 在您的 iis 上安装 iis cors模块

  • 如果是 WebApi 添加:

public static void Register(HttpConfiguration config)
{
    var cors = new EnableCorsAttribute("*", "*", "*");
    cors.SupportsCredentials = true;
    config.EnableCors(cors);
}
  • 将此行添加到您的 web.config:
  <configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add origin="*">
               <allowHeaders allowAllRequestedHeaders="true">
                    <add header="Access-Control-Allow-Origin" />
                    <add header="Access-Control-Allow-Headers" />
                    <add header="Access-Control-Allow-Methods" />
                </allowHeaders>
            </add>
        </cors>
    </system.webServer>
  </configuration>

更多信息。在这篇文章中。

  • 添加xhrFields: {withCredentials: true}到您的 ajax 调用。
于 2021-11-07T07:13:22.490 回答
-1

在 WebApiConfig.cs 中的 EnableCorsAttribute 上启用 SupportCredentials 对我有用:

public static void Register(HttpConfiguration config)
{        
    //enable cors request just from localhost:15136 
    var cors = new EnableCorsAttribute("http://localhost:15136", "*", "*");
    cors.SupportsCredentials = true;
    config.EnableCors(cors);

    //other stuff
}

https://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

{withCredentials :true}确保从 javascript ( )调用时发送凭据

于 2016-11-24T14:21:56.357 回答