CORS的WebAPI使用Windows身份验证 - 允许匿名OPTIONS请求身份验证、WebAPI、CORS、OPTIONS

由网友(温柔似野猫)分享简介:我有Windows身份验证运行的WebAPI 2 REST服务。它是从网站托管分开,所以我使用ASP.NET CORS的NuGet包启用CORS。我的客户网站使用AngularJS。 到目前为止,这是我经历过的:我没得withCredentials设置,所以CORS请求,正在返回加入withCredentials到我的...

我有Windows身份验证运行的WebAPI 2 REST服务。它是从网站托管分开,所以我使用ASP.NET CORS的NuGet包启用CORS。我的客户网站使用AngularJS。

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

我没得withCredentials设置,所以CORS请求,正在返回加入withCredentials到我的$ httpProvider配置解决了一个401。接下来,我已经把我的EnableCorsAttribute使用通配符产地,使用凭据时这是不允许的。通过设定起源的显式列表解决。这使我的GET请求成功,但我的文章发表了preflight请求,我没有创造任何控制器的行动,以支持OPTIONS动词。要解决这个问题,我已经实现了一个的MessageHandler作为全局选项处理。它只是简单地返回200的任何选项的要求。我知道这是不是完美的,但现在的作品,在提琴手。

在哪里我坚持 - 我的角preflight呼叫不包括凭据。根据这个答案,这是由设计,因为OPTIONS请求的设计是匿名的。但是,Windows身份验证停止与401的要求。

我试过把[使用AllowAnonymous]属性我的MessageHandler。在我的dev的电脑,它的工作原理 - OPTIONS动词不需要身份验证,但其他动词做。当我构建和部署到测试服务器,不过,我继续我的OPTIONS请求得到一个401。

是否有可能使用Windows身份验证时,将[使用AllowAnonymous]我的MessageHandler?如果是这样,对任何指导该怎么办呢?或者,这是错误的兔子洞,我应该寻找一种不同的方法?

更新:我能得到它在IIS网站上设置Windows身份验证和匿名身份验证工作。这一切都造成允许匿名,所以我添加授权的一个全球性的过滤器,同时保留使用AllowAnonymous我的MessageHandler。

不过,这感觉就像一个黑客......我一直明白,只有一个身份验证方法应使用(不包括混合)。如果任何人有一个更好的办法,我想它的AP preciate听证会。

解决方案

我用自托管具有的HttpListener和以下解决方案为我工作

我允许anonymus OPTIONS请求启用设置SupportsCredentials CORS真

  

变种CORS =新EnableCorsAttribute(*,*,*);cors.SupportsCredentials = TRUE;config.EnableCors(CORS);VAR监听= appBuilder.Properties [System.Net.HttpListener]作为的HttpListener;如果(听众!= NULL){    listener.AuthenticationSchemeSelectorDelegate =(要求)=> {    如果(的String.Compare(request.HttpMethod,选项,真)== 0)    {             返回AuthenticationSchemes.Anonymous;    }    其他    {             返回AuthenticationSchemes.IntegratedWindowsAuthentication;    }};}

I have a WebAPI 2 REST service running with Windows Authentication. It is hosted separately from the website, so I've enabled CORS using the ASP.NET CORS NuGet package. My client site is using AngularJS.

为 API Gateway REST API 资源启用 CORS

So far, here's what I've been through:

I didn't have withCredentials set, so the CORS requests were returning a 401. Resolved by adding withCredentials to my $httpProvider config. Next, I had set my EnableCorsAttribute with a wildcard origin, which isn't allowed when using credentials. Resolved by setting the explicit list of origins. This enabled my GET requests to succeed, but my POST issued a preflight request, and I hadn't created any controller actions to support the OPTIONS verb. To resolve this, I've implemented a MessageHandler as a global OPTIONS handler. It simply returns 200 for any OPTIONS request. I know this isn't perfect, but works for now, in Fiddler.

Where I'm stuck - my Angular preflight calls aren't including the credentials. According to this answer, this is by design, as OPTIONS requests are designed to be anonymous. However, the Windows Authentication is stopping the request with a 401.

I've tried putting the [AllowAnonymous] attribute on my MessageHandler. On my dev computer, it works - OPTIONS verbs do not require authentication, but other verbs do. When I build and deploy to the test server, though, I am continuing to get a 401 on my OPTIONS request.

Is it possible to apply [AllowAnonymous] on my MessageHandler when using Windows Authentication? If so, any guidance on how to do so? Or is this the wrong rabbit hole, and I should be looking at a different approach?

UPDATE: I was able to get it to work by setting both Windows Authentication and Anonymous Authentication on the site in IIS. This caused everything to allow anonymous, so I've added a global filter of Authorize, while retaining the AllowAnonymous on my MessageHandler.

However, this feels like a hack...I've always understood that only one authentication method should be used (no mixed). If anyone has a better approach, I'd appreciate hearing about it.

解决方案

I used self-hosting with HttpListener and following solution worked for me:

I allow anonymus OPTIONS requests Enable CORS with SupportsCredentials set true

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

阅读全文

相关推荐

最新文章