CORS对OWIN和访问/令牌导致“访问控制允许原因”错误

问题描述:

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

I am having trouble with securing my Web API using owin middle ware.

我已安装在软件包下面

Install-Package Microsoft.Owin.Cors -Version 2.1.0

下面是ConfigureAuth.cs代码。

And below is ConfigureAuth.cs code.

 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

I have hosted this WebApi project on a link , say ,http://webaip.azurewebsites.net

我试图访问上述API的控制器方法从另一个网站,例如, http://mysite.azurewebsites.net
使用上面的代码,我能够调用所有API的方法不安全。 (没有装饰授权属性)通过javascript我不能调用/令牌认证。下面是我的javascript代码。

I am trying to access controller methods of above API from another site, say , http://mysite.azurewebsites.net With above code in place I am able to invoke all the methods of API which are not secure. (Not decorated with Authorize attribute) Through javascript I am not able to invoke /Token for authentication. Below is my javascript code.

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.

注意:我也试图使用下面的代码。它不适用于我。

Note: I have also tried to use below code with. It's not working for me either.

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("*","*","*"));
}


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

the reason you are getting that error is because you have enabled CORS for the webapi but not for your /Token endpoint this gets initialised before the webapi pipeline gets its CORS settings.

除了您已在WebApiConfig.cs中执行的操作

So in addition to what you have already done in your WebApiConfig.cs

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

You should do the following: (assuming you have a standard WebAPI 2 project)

**打开文件:App_Start / IdenityConfig.cs **并添加下面的行//允许cors为..

** Open File: App_Start/IdenityConfig.cs ** and add the line following // Allow cors for the ...

我已将其余项目保留在正常项目模板中。

I have left the rest untouched as in the normal project template

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