如何在WebAPI 2中进行CORS身份validation?

该场景很简单,我需要从另一个服务器(不同于API服务器)login来检索访问令牌。

我在API服务器上安装了Microsoft.Owin.Cors软件包。 在Startup.Auth.cs文件中,在public void ConfigureAuth(IAppBuilder app) ,我join了

 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

WebApiConfig.cs ,在public static void Register(HttpConfiguration config) ,我在这些行中添加了:

 // Cors var cors = new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS"); config.EnableCors(cors); 

我还应该改变什么?

看看我find了什么!

<system.webServer>添加一些自定义标题。

 <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" /> </customHeaders> </httpProtocol> 

然后我可以做CORSauthentication。

我有很多尝试和错误,为基于AngularJS的Web客户端设置它。
对我来说,下面的方法适用于ASP.NET WebApi 2.2和基于OAuth的服务。

  1. 安装Microsoft.AspNet.WebApi.Cors nuget包。
  2. 安装Microsoft.Owin.Cors nuget包。
  3. 添加config.EnableCors(new EnableCorsAttribute("*", "*", "GET, POST, OPTIONS, PUT, DELETE")); 上面的WebApiConfig.Register(config);Startup.cs文件行。
  4. 添加app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);Startup.Auth.cs文件。 这必须在调用IAppBuilder.UseWebApi之前完成
  5. 删除Blaise所做的任何xml设置。

我在这里find了很多设置变化和组合。 所以,布莱斯的做法可能会也可能不会是错的。 这只是我想的另一个设置。

经过许多小时的search,看着许多不同的解决scheme,我已经设法得到这个工作按照下面。

这有几个原因正在发生。 很可能你在错误的地方启用了CORS,或者启用了两次,或者根本没有启用。

如果您正在使用Web API和Owin Token端点,那么您需要在您的Web API方法中删除对CORS的所有引用,并添加正确的owin方法,因为web api cors不会与Token端点一起使用,而Owin cors将同时适用于Web API和令牌authentication端点,让我们开始:

  1. 确保你已经安装了Owin Cors软件包删除任何你有eg.config.EnableCors()的行; 从您的WebAPIconfig.cs文件

  2. 去你的startup.cs文件,并确保你在任何其他configuration运行之前执行Owin Cors。

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); ConfigureAuth(APP);

  3. 如果仍有问题,请转到:Startup.Auth.cs,并确保在ConfigureAuth方法中具有以下内容(如果startup.cs文件正确,则不需要此项)

app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

web.config中

 <appSettings> <add key="cors:Origins" value="*" /> <add key="cors:Headers" value="*" /> <add key="cors:Methods" value="GET, POST, OPTIONS, PUT, DELETE" /> </appSettings> 

Startup.cs

 var appSettings = WebConfigurationManager.AppSettings; // If CORS settings are present in Web.config if (!string.IsNullOrWhiteSpace(appSettings["cors:Origins"])) { // Load CORS settings from Web.config var corsPolicy = new EnableCorsAttribute( appSettings["cors:Origins"], appSettings["cors:Headers"], appSettings["cors:Methods"]); // Enable CORS for ASP.NET Identity app.UseCors(new CorsOptions { PolicyProvider = new CorsPolicyProvider { PolicyResolver = request => request.Path.Value == "/token" ? corsPolicy.GetCorsPolicyAsync(null, CancellationToken.None) : Task.FromResult<CorsPolicy>(null) } }); // Enable CORS for Web API config.EnableCors(corsPolicy); } 

注意 :应该在configurationASP.NET身份之前调用app.UserCors(...)

来源: ASP.NET Web应用程序入门套件 (ASP.NET Web API,Identity,SignalR)

为了详细说明Youngjae的答案,有一个关于使用Web API设置OWIN并在这个过程中启用CORS的很好的教程http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web- API-2-owin-ASP净同一性/

您将需要使用以下命令添加CORS的NuGet包:
Install-Package Microsoft.Owin.Cors -Version 2.1.0

然后添加
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

到Startup.cs中的Configuration方法,所以它看起来像这样:

 public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); ConfigureOAuth(app); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } 

我的答案find了

Web Api 2预测承载令牌的CORS请求

具体来说,使用OAuthAuthorizationServerProvider.GrantResourceOwnerCredentials实现的/ Token请求是再次添加头。 在任何其他OWINconfiguration之前添加OWIN CORS的东西,并从GrantResourceOwnerCredentials中删除标题,按照该链接,瞧。 祝你好运。

我只想分享我的经验。 我花了一半的时间敲我的头,并试图使其工作。 我读了很多文章和SO问题,最后我发现了什么是错的。

该线

 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 

不是StartupConfiguration方法中的第一个。 当我把它移到最顶端 – 所有的东西都开始神奇地工作了。

web.configconfig.EnableCors(corsPolicy);没有自定义标题config.EnableCors(corsPolicy); 或其他任何东西都是必要的

希望这会帮助别人节省一些时间。

添加客户头可能不会给您足够的自由来定制您的安全需求。 它向世界敞开了所有其他部分。 下面的代码只是为“token”做的,控制器的其他部分应该通过EableCors注解完成。

 public void ConfigureAuth(IAppBuilder app) { //other stuff app.Use(async (context, next) => { IOwinRequest req = context.Request; IOwinResponse res = context.Response; if (req.Path.StartsWithSegments(new PathString("/Token"))) { var origin = req.Headers.Get("Origin"); if (!string.IsNullOrEmpty(origin)) { res.Headers.Set("Access-Control-Allow-Origin", origin); } if (req.Method == "OPTIONS") { res.StatusCode = 200; res.Headers.AppendCommaSeparatedValues("Access-Control- Allow-Methods", "GET", "POST"); res.Headers.AppendCommaSeparatedValues("Access-Control- Allow-Headers", "authorization", "content-type"); return; } } await next(); }); //other stuff } 

要启用Cors,请按照此处的说明进行操作。

当使用OWIN中间件处理CORS时,我们不需要在WebAPIConfig或web.config文件中添加标题。 是的,当你需要公共访问的时候,在web.config文件中添加头文件是行不通的,但是如果你需要限制基于白名单(域)的访问,那么允许所有访问不再是你想要的。

有了OWINS,我们可以通过实现这个处理程序来处理这个问题

 OAuthAuthorizationServerProvider.MatchEndpoint 

使用这个处理程序,我们可以检测请求方法(OPTIONS,POST …),并且如果请求应该被视为授权或令牌端点。 这是可以添加逻辑来检查Origin标头(请求)的区域,并且通过添加响应标头Access-Control-Allow-Origin来validation是否允许该域。

 string origin = context.Request.Headers.Get("Origin"); var found = IsDomainAllowed(origin); if (found){ context.Response.Headers.Add("Access-Control-Allow-Origin", new string[] { origin }); } 

欲了解更多背景,请看这个链接: http : //www.ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html

你可以在这里find你需要在不同的范围启用CORS的多种方式: http : //www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

无论如何,我有同样的问题,并通过以不同的方式添加标题没有得到完整的解决scheme。

我发现如果不指定相反的话,IIS会使用处理程序来覆盖CORS Web应用程序configuration。

就我而言,我还必须通过在我的应用程序的主Web.config中添加以下configuration来删除IIS处理程序的用法:

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

请注意,当您根据创build的项目types创build新项目时,可能会默认设置此configuration,但是如果您从头开始,则可能需要添加此configuration。

完整的解决scheme。 你只需要改变一些文件,为我工作。

Global.ascx

 public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { WebApiConfig.Register(GlobalConfiguration.Configuration); } } 

WebApiConfig.cs

所有的请求都调用这个代码。

 public static class WebApiConfig { public static void Register(HttpConfiguration config) { EnableCrossSiteRequests(config); AddRoutes(config); } private static void AddRoutes(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "Default", routeTemplate: "api/{controller}/" ); } private static void EnableCrossSiteRequests(HttpConfiguration config) { var cors = new EnableCorsAttribute( origins: "*", headers: "*", methods: "*"); config.EnableCors(cors); } } 

一些控制器

没有什么改变。

Web.config文件

你需要在你的web.config中添加处理程序

 <configuration> <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> </configuration>