OWIN上的CORS和访问/令牌导致'Access-Control-Allow-Origin'错误

时间:2014-11-04 00:36:14

标签: 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);    
      ///Install-Package Microsoft.Owin.Cors -Version 2.1.0
      app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
  }

我在一个链接上托管了这个WebApi项目,比如http://webaip.azurewebsites.net

我正在尝试从其他网站访问上述API的控制器方法,例如http://mysite.azurewebsites.net 有了上面的代码,我可以调用所有不安全的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("*","*","*"));
}

8 个答案:

答案 0 :(得分:40)

经过数小时的搜索并查看了许多不同的解决方案后,我已按照以下方式设法实现了这一目标。

这种情况有很多原因。很可能你在错误的地方启用了CORS,或者启用了两次或根本没启用。

如果您正在使用Web API和Owin Token端点,那么您需要删除Web API方法中对CORS的所有引用并添加正确的owin方法,因为web api cors将无法使用Token端点,而Owin cors将工作对于Web API和令牌验证端点,让我们开始:

  1. 确保已安装Owin Cors包
  2. 删除您拥有的任何行eg.config.EnableCors();来自您的WebAPIconfig.cs 档案
  3. 转到startup.cs文件并确保执行Owin 在任何其他配置运行之前的Cors。

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        ConfigureAuth(app);
    
  4. 如果仍有问题请访问:Startup.Auth.cs并确保您的ConfigureAuth方法中包含以下内容(如果您的startup.cs文件正确,则不需要此内容)

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

答案 1 :(得分:20)

您收到该错误的原因是因为您已为webapi启用了CORS,但没有为您的/ Token端点启用此功能,这在webapi管道获取其CORS设置之前已初始化。

除了您在WebApiConfig.cs中已经完成的内容之外

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

**打开文件:App_Start / IdenityConfig.cs **并添加以下行//允许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;
    }

答案 2 :(得分:3)

请参阅我对this问题

的回答

此外,如果您使用angularJS作为客户端,您可以查看我的article,其中显示了如何使用AngularJS Client中的Web API 2(个人用户帐户+启用CORS)。

希望有所帮助。

答案 3 :(得分:2)

也可以使用此解决方案:

打开providers文件夹,然后打开ApplicationOAuthProvider.cs

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

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

答案 4 :(得分:1)

如果有人发现这个有用的

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

            });

答案 5 :(得分:0)

您不应两次使用相同的标头(我认为这是字典数据结构)

在我的情况下,我在提供程序类中有此行,因为我已经在startup.cs中启用了内核,所以不需要此行。

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

在我拥有并保留的startup.cs中

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

答案 6 :(得分:0)

有同样的问题。 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;
                    }
                }


               ...```

答案 7 :(得分:-2)

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

在Startup.cs中启用它

        config.EnableCors();

然后你可以做任何你想做的事情:

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

 [EnableCors([theHostYouWant], "*", "*")]

要允许外部身份验证,应用程序需要访问“/ Token”,允许这样做,在

 [YourApiFolder]/Providers/ApplicationoAuthProvider.cs

找到

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

添加

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

这涵盖了控制器和“/ Token”,该属性也可以在控制器方法中添加。所以它可以解决所有问题。