OWIN上的CORS和访问/令牌原因';访问控制允许原点';错误

OWIN上的CORS和访问/令牌原因';访问控制允许原点';错误,cors,asp.net-web-api2,Cors,Asp.net Web Api2,我在使用owin中间件保护我的Web API时遇到问题 我已经安装了下面的软件包 Install-Package Microsoft.Owin.Cors -Version 2.1.0 下面是ConfigureAuth.cs代码 public void ConfigureAuth(IAppBuilder app) { //... app.UseOAuthBearerTokens(OAuthOptions); ///I

我在使用owin中间件保护我的Web API时遇到问题

我已经安装了下面的软件包

Install-Package Microsoft.Owin.Cors -Version 2.1.0
下面是ConfigureAuth.cs代码

 public void ConfigureAuth(IAppBuilder app)
 {                
      //...
      app.UseOAuthBearerTokens(OAuthOptions);    
      ///Install-Package Microsoft.Owin.Cors -Version 2.1.0
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
  }
我在一个链接上主持了这个WebApi项目

我试图从另一个站点访问上述API的控制器方法,比如, 有了上面的代码,我就能够调用API中所有不安全的方法。(未使用Authorize属性修饰)通过javascript,我无法调用/Token进行身份验证。下面是我的javascript代码

function LogIn() {
            var loginData = {
                grant_type: 'password',
                username: 'username',
                password: 'password',                
            };

            $.ajax({
                type: 'POST',
                url: 'http://webaip.azurewebsites.net/Token/',
                data: loginData               

            }).done(function (data) {
                alert('logged in');
                alert(data);
            }).fail(function (data) {
                alert('login problem')
            }).error(function (data) {
                alert('error invoking API');
            });
            return false;
        }
我正在犯错误

XMLHttpRequest cannot load http://webaip.azurewebsites.net/Token/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 404.
注意:我也尝试使用下面的代码。这对我也不管用

public static void Register(HttpConfiguration config)
{
     var json = config.Formatters.JsonFormatter;
     config.Formatters.Remove(config.Formatters.XmlFormatter);
     //Need to have  Microsoft.AspNet.WebApi.Cors package installed.
     config.EnableCors(new EnableCorsAttribute("*","*","*"));
}
请看我的问题答案

另外,如果您使用angularJS作为您的客户端,您可以查看my,其中显示了如何从angularJS客户端使用WebAPI2(个人用户帐户+启用CORS)


希望这能有所帮助。

您出现此错误的原因是您已为webapi启用CORS,但未为您的/Token端点启用CORS。在webapi管道获取其CORS设置之前,此项已初始化

因此,除了您在WebApiConfig.cs中已经完成的工作之外

您应该执行以下操作:(假设您有一个标准的WebAPI 2项目)

**打开文件:App_Start/IdenityConfig.cs**并在//Allow cors后面添加一行,用于

我没有像在正常的项目模板中那样触及其余部分

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        // Allows cors for the /token endpoint this is different from webapi endpoints. 
        context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });  // <-- This is the line you need

        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<IdentityDb>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = true,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = false,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

       // rest ommited ... 
        return manager;
    }
公共静态应用程序服务器管理器创建(IdentityFactoryOptions选项,IOwinContext上下文)
{
//允许/token端点的cors这与webapi端点不同。

context.Response.Headers.Add(“Access Control Allow Origin”,new[]{“*”});//此解决方案也可用于:

打开提供程序文件夹,然后打开ApplicationAuthProvider.cs

在GrantResourceOwnerCredentials()函数中粘贴此行:

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

经过几个小时的搜索和寻找许多不同的解决方案,我已经设法让这个工作如下

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

如果您使用的是Web API和Owin令牌端点,那么您需要删除Web API方法中对CORS的所有引用,并添加正确的Owin方法,因为Web API CORS将不适用于令牌端点,而Owin CORS将适用于Web API和令牌身份验证端点,因此让我们开始:

  • 确保已安装Owin Cors软件包
  • 从WebAPIconfig.cs中删除所有行,例如.config.EnableCors() 文件
  • 转到startup.cs文件,确保执行Owin 在运行任何其他配置之前,先执行Cors

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        ConfigureAuth(app);
    
  • 如果仍然存在问题,请转到:Startup.Auth.cs,并确保您的ConfigureAuth方法中包含以下内容(如果Startup.cs文件正确,则不需要此选项)

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


  • 第一步是安装CORS nuget:Microsoft.AspNet.WebApi.Core

    在Startup.cs中启用它

            config.EnableCors();
    
    然后你可以做任何你想做的事情:

    要允许控制器向外部应用程序公开,请添加以下属性:

     [EnableCors([theHostYouWant], "*", "*")]
    
    若要允许外部身份验证,应用程序需要访问“/令牌”,若要允许,请在

     [YourApiFolder]/Providers/ApplicationoAuthProvider.cs
    
    发现


    这包括控制器和“/Token”,该属性也可以添加到控制器方法中。因此,它可以解决所有问题。

    如果有人认为这很有用

    app.Use(async (context, next) =>
                {
                    context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:52436" });
                    await next();
    
                });
    

    您不应该有两次相同的头(我认为这是一个字典数据结构)

    在我的例子中,我在一个provider类中使用了这一行,这是不需要的,因为我已经在startup.cs中启用了核心

    //context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
    
    在startup.cs中,我拥有并保持:

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

    也有同样的问题。Owin和WebAPI冲突,所以两者都可以工作,但不能一起工作

    我在Startup.Auth.cs中的解决方案

                {
                    var cultureQuery = context.Request.Query["culture"];
    
                    IOwinRequest req = context.Request;
                    IOwinResponse res = context.Response;
                    if (req.Path.StartsWithSegments(new PathString("/Token")))
                        {
                        // if there is an origin header
                        var origin = req.Headers.Get("Origin");
                        if (!string.IsNullOrEmpty(origin))
                        {
                            // allow the cross-site request
                            res.Headers.Set("Access-Control-Allow-Origin", origin);
                        }
                        // if this is pre-flight request
                        if (req.Method == "OPTIONS")
                        {
                            // respond immediately with allowed request methods and headers
                            res.StatusCode = 200;
                            res.Headers.AppendCommaSeparatedValues("Access-Control-Allow- 
                            Methods", "GET", "POST");
                            res.Headers.AppendCommaSeparatedValues("Access-Control-Allow- 
                            Headers", "authorization");
                            // no further processing
                            return;
                        }
                    }
    
    
                   ...```
    
    

    它对/token有效,但现在开始对/api抛出相同的问题…:(如果我删除了你提到的行,/api开始正常工作……这造成了无尽的挫折。感谢你发布你的答案——如果没有它,我将损失数小时。在我的情况下,控件甚至不会使用此方法。GrantResourceOwnerCredentials我应该如何以及在何处添加标题?嘿,感谢你的跟进,我忘了更新此标题。)我通过将cors代码放在Startup classs.app.UseCors(CorsOptions.AllowAll)的public void ConfigureAuth(IAppBuilder app)中来实现它;解决方案是删除该选项,就像您在
    Startup.cs
    中启用了CORS一样。这是唯一对我的团队有效的答案。所有其他答案都破坏了应用程序的其余部分。感谢您解释删除其他CORS配置的必要性。@SouthShoreAK很高兴我经历了同样的痛苦。我唯一需要添加的是人需要知道如何添加Owin.Cors包。对我来说,执行第3步就足够了。@PiotrStulinski,你救了我的命,为此花了一整天的时间。在网上搜索3天后,它终于对我起作用了。这个解决方案对我起作用了。我只执行了第1步和第2步…..非常感谢你…..这篇帖子…..)我认为您需要将app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    放在第一行
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    
                {
                    var cultureQuery = context.Request.Query["culture"];
    
                    IOwinRequest req = context.Request;
                    IOwinResponse res = context.Response;
                    if (req.Path.StartsWithSegments(new PathString("/Token")))
                        {
                        // if there is an origin header
                        var origin = req.Headers.Get("Origin");
                        if (!string.IsNullOrEmpty(origin))
                        {
                            // allow the cross-site request
                            res.Headers.Set("Access-Control-Allow-Origin", origin);
                        }
                        // if this is pre-flight request
                        if (req.Method == "OPTIONS")
                        {
                            // respond immediately with allowed request methods and headers
                            res.StatusCode = 200;
                            res.Headers.AppendCommaSeparatedValues("Access-Control-Allow- 
                            Methods", "GET", "POST");
                            res.Headers.AppendCommaSeparatedValues("Access-Control-Allow- 
                            Headers", "authorization");
                            // no further processing
                            return;
                        }
                    }
    
    
                   ...```