CORS on OWIN and accessing /token causes 'Access-Control-Allow-Origin' error

为君一笑 提交于 2019-11-28 17:55:47

After many hours of searching and looking at many many different solutions to this i have managed to get this working as per the below.

There are a number of reasons this is happening. Most likely you have CORS enabled in the wrong place or it is enabled twice or not at all.

If you are using Web API and Owin Token end point then you need to remove all the references to CORS in your Web API method and add the correct owin method because web api cors will not work with Token endpoint whilst Owin cors will work for both Web API and Token auth end points so lets begin:

  1. Make sure you have the Owin Cors package installed
  2. Remove any line that you have eg.config.EnableCors(); from your WebAPIconfig.cs file
  3. Go to your startup.cs file and make sure you execute Owin Cors before any of the other configuration runs.

        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        ConfigureAuth(app);
    
  4. If your still having problems go to: Startup.Auth.cs and ensure you have the following in your ConfigureAuth method (you shouldnt need this if your startup.cs file is correct)

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

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.

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

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

** 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;
    }
Omar.Alani

See my answer for this question

Also, if you use an angularJS as your client, you can have a look to my article that shows how to use Web API 2 (Individual User Account + CORS Enabled) from AngularJS Client.

Hope that helps.

This solution can also be used:

open providers folder and then open ApplicationOAuthProvider.cs

inside GrantResourceOwnerCredentials() function paste this line:

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

In case, anyone finds this useful

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

            });

You should not have same header twice (I think it is a dictionary data structure)

In my case I had this line in a provider class which was not needed because I'm already enabling cores in startup.cs

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

in startup.cs I had and I kept:

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

The first step is to install CORS nuget: Microsoft.AspNet.WebApi.Core

Enable it in Startup.cs

        config.EnableCors();

then you can do anything you want:

to allow a controller to expose to external application, add this attribute:

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

to allow external authentication, application need access to "/Token", to allow this, in

 [YourApiFolder]/Providers/ApplicationoAuthProvider.cs

find

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

add

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

this covers both the controller and "/Token", the attribute can also added in the controller methods. So it can solve all the problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!