首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Windows身份验证的WebAPI CORS -允许匿名选项请求

Windows身份验证的WebAPI CORS -允许匿名选项请求
EN

Stack Overflow用户
提问于 2014-12-11 02:37:56
回答 9查看 23.8K关注 0票数 23

我有一个带有的WebAPI 2 REST服务。它与网站分开托管,所以我已经使用ASP.NET CORS NuGet包启用了CORS。我的客户站点正在使用AngularJS。

到目前为止,我所经历的是:

  1. 我没有设置withCredentials,所以CORS请求返回401。通过将withCredentials添加到$httpProvider配置中来解决问题。
  2. 接下来,我将EnableCorsAttribute设置为通配符来源,这在使用凭据时是不允许的。通过设置明确的起源列表来解决。
  3. 这使我的GET请求能够成功,但我的帖子发出了飞行前请求,而且我没有创建任何支持OPTIONS谓词的控制器操作。为了解决这个问题,我实现了一个MessageHandler作为全局选项处理程序。它只是对任何选项请求返回200。我知道这并不完美,但现在在Fiddler行得通。

在我被困的地方-我的飞行前通话不包括凭据。根据this answer的说法,这是经过设计的,因为选项请求是设计为匿名的。但是,Windows身份验证使用401停止请求。

我已经尝试将AllowAnonymous属性放在MessageHandler上。在我的dev计算机上,它可以工作-选项谓词不需要身份验证,但其他谓词需要。但是,当我构建并部署到测试服务器时,我将继续在我的选项请求中获得401。

当使用AllowAnonymous身份验证时,可以在我的MessageHandler上应用MessageHandler吗?如果是的话,有何指导意见?或者这是个错误的兔子洞,我应该换个方法?

更新:我能够通过在IIS中的站点上设置Windows身份验证和匿名身份验证来使其工作。这导致一切都允许匿名,因此我添加了一个全局授权筛选器,同时将AllowAnonymous保留在我的MessageHandler上。

然而,这感觉就像一次黑客攻击……我一直都明白,应该只使用一种身份验证方法(不能混合)。如果有人有更好的方法,我会很感激听到这件事。

EN

回答 9

Stack Overflow用户

发布于 2015-03-24 13:00:07

我在HttpListener中使用了自托管,下面的解决方案对我有用:

  1. 我允许匿名选项请求
  2. 启用SupportsCredentials设置为true的CORS

代码语言:javascript
运行
复制
var cors = new EnableCorsAttribute("*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
var listener = appBuilder.Properties["System.Net.HttpListener"] as HttpListener;
if (listener != null)
{
    listener.AuthenticationSchemeSelectorDelegate = (request) => {
    if (String.Compare(request.HttpMethod, "OPTIONS", true) == 0)
    {
        return AuthenticationSchemes.Anonymous;
    }
    else
    {
        return AuthenticationSchemes.IntegratedWindowsAuthentication;
    }};
}
票数 17
EN

Stack Overflow用户

发布于 2017-01-23 13:30:02

为了使CORS请求在以下约束范围内工作(非常类似于OP的约束),我已经挣扎了一段时间:

  • 所有用户的Windows身份验证
  • 不允许匿名身份验证
  • 与IE11一起工作,in some cases不发送CORS飞行前请求(或至少不将global.asax BeginRequest作为选项请求发送)。

我的最后配置如下:

web.config -允许未经身份验证(匿名)的飞行前请求(选项)

代码语言:javascript
运行
复制
<system.web>
    <authentication mode="Windows" />
    <authorization>
        <allow verbs="OPTIONS" users="*"/>
        <deny users="?" />
    </authorization>
</system.web>

global.asax.cs -使用允许来自另一个域的调用方接收数据的标头正确地回答

代码语言:javascript
运行
复制
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (Context.Request.HttpMethod == "OPTIONS")
    {
        if (Context.Request.Headers["Origin"] != null)
            Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);

        Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, MaxDataServiceVersion");
        Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        Response.End();
    }
}

CORS启用

代码语言:javascript
运行
复制
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // all requests are enabled in this example. SupportsCredentials must be here to allow authenticated requests          
        var corsAttr = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
        config.EnableCors(corsAttr);
    }
}

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}
票数 15
EN

Stack Overflow用户

发布于 2016-06-03 17:37:54

这是一个简单得多的解决方案--几行代码允许所有“选项”请求有效地模拟应用程序池帐户。您可以将匿名关闭,并根据正常实践配置CORS策略,但随后将以下内容添加到global.asax.cs中:

代码语言:javascript
运行
复制
            protected void Application_AuthenticateRequest(object sender, EventArgs e)
            {
                if (Context.Request.HttpMethod == "OPTIONS" && Context.User == null)
                {
                    Context.User = System.Security.Principal.WindowsPrincipal.Current;
                }
            }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27414487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档