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


74

场景很简单,我需要从另一台服务器(不同于API服务器)登录以检索访问令牌。

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

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

我还应该改变什么?


6
app.UseCors(CorsOptions.AllowAll)-为对您网站的所有跨域请求启用CORS。config.EnableCors(..)仅针对Web Api启用CORS
Konstantin Tarkus

Answers:


78

看看我发现了什么!

在中添加一些自定义标头<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>

然后,我可以进行CORS身份验证。


4
我不知道如果没有您的帖子我怎么能解决这个问题;谢谢!Web API文档未提及这些配置要求... goo.gl/s9K6o2goo.gl/G8jKG0
TheFastCat 2013年

2
不幸的是,正如人们所说的那样,OWIN身份验证管道上的内容是1)覆盖了我已经通过context.Request.Headers作为OWIN中间件的一部分编写的任何响应2)即使配置了自定义策略,也忽略了OWIN针对“ / token”请求进行操作。至少出于测试目的,我不确定目前是否有很多选择。

1
我认为真正应该发生的是,我们应该使用称为login的东西将令牌方法包装到帐户控制器中,然后标准的cors配置就可以完成工作。
洪添

7
这不是一个很好的解决方案。它可以工作,但是等同于关闭防火墙而不是对其进行正确配置。
Piotr Stulinski

2
我不同意。CORS不能解决任何问题。防火墙可以保护客户端,但是CORS被(错误地)用作保护服务器的一种方式,但是简单的客户端更改请求标头就可以了。只需使用例如chrome --disable-web-security标志或搜索Allow-Control-Allow-Origin:* Chrome扩展。
Peheje '16

50

我为基于AngularJS的Web客户端设置了很多尝试和错误。
对我而言,以下方法适用于ASP.NET WebApi 2.2和基于OAuth的服务。

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

在这里的stackoverflow或博客文章中,我发现了许多设置变化和组合。因此,布莱斯的做法可能是错误的,也可能不是错误的。我认为这只是另一个设置。


4
这可能会产生以下问题:aspnetwebstack.codeplex.com/workitem/1539
Kovachev

2
我分别使用app.UseCorsconfig.EnableCors方法在OWIN和Web API配置中启用了CORS ,但是OWIN/token端点似乎被特殊对待,并且未在响应中发送Access-Control-Allow-Origin HTTP标头。即使在实施下面的Konstantin Tarkus的自定义策略解决方案时也是如此。

1
你需要一个NuGet包“Microsoft.AspNet.WebApi.Cors”有类和方法步骤1
扬Zahradnik的

3
我必须安装Microsoft.Owin.Cors以及
galdin

33

经过数小时的搜索并查看了许多不同的解决方案,我设法按照以下方法进行工作。

发生这种情况有多种原因。您很可能在错误的位置启用了CORS,或者启用了两次或根本没有启用。

如果您使用的是Web API和Owin令牌端点,则需要删除Web API方法中对CORS的所有引用,并添加正确的owin方法,因为Web api cors不能与Token端点一起使用,而Owin cors可以同时用于两个Web上。 API和令牌认证端点,因此让我们开始吧:

  1. 确保已安装Owin Cors软件包。删除所有具有eg.config.EnableCors();的行。从您的WebAPIconfig.cs文件

  2. 转到您的startup.cs文件,并确保在运行任何其他配置之前执行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);


2
谢谢@Piotr,这是真正的工作答案。布莱斯能否将其标记为真实答案?与其他所有答案一样,OWIN / Token或WebAPI可以一起工作,而不能一起工作。就我而言,在Web.config加上config.EnableCors(...)中添加XML会导致添加重复的标题[Access-Control-Allow-Headers],Chrome中禁止这样做。
刘Joe雄

在项目中同时包含OWIN和Web API Cors之后,我也面临着重复的标头问题。但是正如@Piotr在回答中指出的那样,仅OWIN CORS足以解决它。
Dipendu Paul

1
这是最好的答案。非常感谢。另外,您可能需要Microsoft.AspNet.WebApi.OwinSelfHost程序包和Microsoft.Owin.Cors程序包才能使用IAppBuilder(应用程序)的UseCors函数
janaka aravinda

21

web.config

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

启动文件

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

注意事项app.UserCors(...)应在配置ASP.NET Identity之前调用。

来源:ASP.NET Web应用程序入门工具包(ASP.NET Web API,Identity,SignalR)


我已经实现了这一点,但很惊讶地发现,在调试器中验证策略代码的执行是否有效,HTTP响应中没有针对“ / token”请求的Access-Control-Allow-Origin标头。

奇怪的是,通过手动添加响应头(而不是通过任何OWIN或Web API CORS配置)通过web.config启用CORS之后,将其删除并重新启用我的API配置之后,“ / token”的问题就消失了。不知道发生了什么,但是问题现在已经消失了。

1
请记住,.EnableCors()在OWIN管道中放置的顺序很重要。您想把它放在其他OWIN中间件之前。
康斯坦丁·塔尔库斯

这是api网站还是客户端网站的web.config?
曼努埃尔·埃尔南德斯

@KonstantinTarkus您好,我只允许来自某些网址的http请求。我应该在<add key =“ cors:Origins” value =“ *” />中代替什么。可以发出请求的唯一URL是localhost:777。?
Alex

15

为了详细介绍Youngjae的答案,有一个很棒的教程,内容是使用Web API设置OWIN并在以下过程中启用CORS: http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web- api-2-owin-asp-net-identity /

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

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

到Startup.cs中的Configuration方法,因此它类似于:


8
这对我不起作用。而且我认为最初的问题就是关于为什么app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 不起作用。
Milen Kovachev 2014年

我分别使用app.UseCorsconfig.EnableCors方法在OWIN和Web API配置中启用了CORS ,但是OWIN/token端点似乎被特殊对待,并且未在响应中发送Access-Control-Allow-Origin HTTP标头。即使在实施下面的Konstantin Tarkus的自定义策略解决方案时也是如此。


9

我只想分享我的经验。我花了一半的时间来敲打头,努力使它正常工作。我读了许多文章和SO问题,最后我弄清楚了什么地方出了问题。

线

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

不是Startup班上第一个Configuration方法中。当我将它移到顶部时,一切开始神奇地工作。

而在没有自定义页眉web.configconfig.EnableCors(corsPolicy);或其他任何东西是必要的。

希望这可以帮助某人节省一些时间。


1
在我的作业到期前30分钟为我节省了时间:)谢谢!#魔术大声笑
Norman Bentley

即使我将其添加为启动类配置方法中的第一行,也会出现错误。但是,当我将配置与此行一起添加时,它会引发重复的问题。
bomaboom

4

您可以在这里找到在不同范围内启用CORS的多种方法: http //www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

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

我发现IIS使用的处理程序会在您未指定相反的情况下覆盖您的CORS Web应用程序配置。

就我而言,我还必须通过在应用程序的主Web.config中添加以下配置来删除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>

请注意,根据新项目的类型,在创建新项目时可能会默认设置此配置,但是如果从头开始,则可能必须添加此配置。


是! 在开发过程中使用JSONP一直困扰着我。如您所说,从头开始。
tigerswithguitars

2

添加客户标题可能不会给您太多自定义安全需求的自由。它向世界开放了api的所有其他部分。以下代码仅针对“令牌”执行此操作,并且应通过EableCors注释完成api控制器的其他部分。

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


1

使用OWIN中间件处理CORS时,我们不需要在WebAPIConfig或web.config文件上添加标头。是的,当您想要公共访问时,可以在web.config文件中添加标头确实可以,但是如果您需要基于白名单(域)限制访问,则不再允许“全部”访问。

使用OWINS,我们可以通过实现以下处理程序来解决此问题:

使用此处理程序,我们可以检测请求方法(OPTIONS,POST ...)以及是否应将请求视为Authorize或Token端点。这是可以在其中添加逻辑以检查Origin头(请求)并通过添加响应头Access-Control-Allow-Origin来验证是否应允许该域的区域。

有关此背景的更多信息,请查看以下链接:http : //www.ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html


0

完全溶解。您只需要更改一些文件,即可为我工作。

Global.ascx

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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.