CORS is not working in web api with OWIN authentication

36,760

Solution 1

Be sure you've got only

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

configured, and not also the old style 'config.EnableCors()' in your Global.asax or WebApiConfig. Furthermore: place the above statement as the first one in your owin Startup class. Yes that really makes a difference, setting it later can also cause cors to not work.

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        ... etc

Solution 2

OWIN and Microsoft.AspNet.WebApi.Cors are two separate libraries and each one needs separate configuration.

Disable use of CORS with OWIN:

public void Configuration(IAppBuilder app)
{
        //app.UseCors(CorsOptions.AllowAll);

Find GrantResourceOwnerCredentials method and add Access-Control-Allow-Origin to context so when it returns a call after authentication is completed that browser finds the header and accepts it.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost" });

Now install Microsoft.AspNet.WebApi.Cors package from Nuget to your webapi project, and add this to Register method

public static void Register(HttpConfiguration config)
{
        var cors = new EnableCorsAttribute("http://localhost, ", "accept,accesstoken,authorization,cache-control,pragma,content-type,origin", "GET,PUT,POST,DELETE,TRACE,HEAD,OPTIONS");

        config.EnableCors(cors);

This did it for me.

Solution 3

Especially if you are having problem with the Web API bearer token when using CORS then dont forget to put "TOKEN" in the list of your allowed methods.

Please put the code in your system.webServer of web.config, that is how i solved mine

<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE, TOKEN" />
 </customHeaders>

Solution 4

Had the same problem. In addition to the above indications (using app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll) only, and setting it up as first thing), I had to specify the following in the application Web.config file to be able to handle Option Requests:

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

Due to some headers that I was sending in the authentication request, an Options request is sent before the actual POST request, and it needs to return the correct 'Access-Control-Allow-Origin' header before the POST is sent.

If none of the CORS headers are returned by the options response, then the POST will not be sent at all. The added configuration enables this behaviour as well as for Trace.

As explained in this post

Share:
36,760

Related videos on Youtube

Binson Eldhose
Author by

Binson Eldhose

A programmer,

Updated on July 09, 2022

Comments

  • Binson Eldhose
    Binson Eldhose almost 2 years

    In my application i am using web api with token based authentication with CORS support, but when client request for the token, an error occured due to CORS (Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at (my site name) . This can be fixed by moving the resource to the same domain or enabling CORS.)

    I had configured everything required for CORS support ( i think so). here my configuration

    Owin start up class

       public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
    
    
                var config = new HttpConfiguration
                {
                    DependencyResolver = new StructureMapWebApiDependencyResolver(container)
    
                };
    
    
                WebApiConfig.Register(config);  // registering web api configuration
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  // cors for owin token pipeline
                app.UseWebApi(config);
                ConfigureOAuth(app);
    
    
            }
    
            public void ConfigureOAuth(IAppBuilder app)
            {
                var oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
                {
    
                    AllowInsecureHttp = true,
                    TokenEndpointPath = new PathString("/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                    Provider = new SimpleAuthorizationServerProvider()
                };
                // Token Generation
                app.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);
                app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    
            }
        }
    

    And my webapi configuration

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                config.EnableCors();  // Corse support for Web api
                config.MapHttpAttributeRoutes(); // attribute based urls
    
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
            }
        }
    

    here configuration in web.config

    <system.webserver>
     <httpProtocol>
          <customHeaders>
            <!-- Adding the following custom HttpHeader will help prevent CORS from stopping the Request-->
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
          </customHeaders>
        </httpProtocol>
    </system.webserver>
    

    and my request header from mozilla

    Accept  application/json, text/plain, */*
    Accept-Encoding gzip, deflate
    Accept-Language en-US,en;q=0.5
    Content-Length  67
    Content-Type    application/x-www-form-urlencoded; charset=UTF-8
    Host    talenterp
    Origin  http://192.168.1.11:85
    Referer http://192.168.1.11:85/
    User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
    

    The URLs of Apps are

    Server app (which should support CORS)

    {http://talenterp}
    

    Token end point :

    {http://talenterp/token}
    

    Client app

    {http://talentmvc:85}
    

    NB: I already added

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

    in GrantResourceOwnerCredentials() method of my AuthorizationServerProvider

    • Binson Eldhose
      Binson Eldhose almost 10 years
      resolved.. the problem was over configuration CORS app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); config.EnableCors(); context.OwinContext.Response.Headers.Add("Access-Control-All‌​ow-Origin", new[] { "*" }); i just removed first one
    • Rodrigo Longo
      Rodrigo Longo over 9 years
      Hi! This really worked for you? Thanks.
    • Echiban
      Echiban almost 9 years
      It is probably better to remove the config.EnableCors() line rather than the app.UserCors(). The former doesn't use OWIN, the latter does. Moving forward it's better to use OWIN pipeline setups.
    • Elger Mensonides
      Elger Mensonides about 8 years
      @BinsonEldhose please accept an anwer.
    • Toolkit
      Toolkit over 5 years
      You also need to remove <customHeaders> from web.config, see stackoverflow.com/a/33664502/631527
  • fiberOptics
    fiberOptics about 8 years
    How can we customize the CORS in OWIN? like for example, I want to allow only this url: myapp.com
  • Elger Mensonides
    Elger Mensonides about 8 years
    @fiberOptics create a CorsPolicy for that and add the origins you want, create a policyProvider and add that to a CorsOptions object
  • Matze
    Matze about 8 years
    This article describes how to provide a custom CORS policy: benfoster.io/blog/aspnet-webapi-cors
  • Jan Zahradník
    Jan Zahradník over 7 years
    This should be marked as a correct answer nowadays. Thank you!
  • Ehsan Zargar Ershadi
    Ehsan Zargar Ershadi over 7 years
    actually this worked for me, for upper version on owin this worked out. +1
  • David Maisuradze
    David Maisuradze about 7 years
    I know it have passed nearly 6 months since you posted this answer but maybe you still remember this. I am interested in, why did you write "http: //localhost, " in var cors=new EnableCorsAttribute("http: //localhost, "... and just not var cors=new EnableCorsAttribute("http: //localhost"... ? I mean I am confused with ", "(comma and space) after "http: //localhost
  • Dado Kljuco
    Dado Kljuco about 7 years
    @Dato that's definitely a leftover from the list of domains that I had in my code. The EnableCorsAttribute allows you pass a list of domains in one string. Here is a reference link
  • David Maisuradze
    David Maisuradze about 7 years
    @DadoKljuco Thanks for your response. Funny thing is that var cors=new EnableCorsAttribute("http: //localhost, "... works nice but var cors=new EnableCorsAttribute("http: //localhost"... fails. And this was the reason why I was confused
  • John Livermore
    John Livermore about 7 years
    Moved the UseCors call to the first in the Configuration method, and it solved our 405 issue. Postman worked fine, but it was 405ing from Chrome.
  • Craig
    Craig over 6 years
    Moving the line up to the top of the Configuration method fixed mine too. Thanks!
  • Pogrindis
    Pogrindis about 6 years
    place the above statement as the first one in your owin Startup class. .... 2 hours of my life wasted...
  • Amir Oveisi
    Amir Oveisi over 4 years
    adding TOKEN to values fixed my problem while all other solutions was not working!
  • Kushal Shah
    Kushal Shah about 4 years
    @Pogrindis only two hours? I remember when first dealing with WebApi wasting much longer on what turned out to be just a middleware registration order issue.
  • Pogrindis
    Pogrindis about 4 years
    @Ted I bet you wont waste even 10 mins when you come across it again ;) - Don't worry though, I've had the embarrassment of googling things, finding results of SO and realizing I posted the answer.. We're all allowed our senior moments!
  • Kushal Shah
    Kushal Shah about 4 years
    And again, and again @Pogrindis. Some kind of "stackenfreude" where you delight in your own misfortune as it leads you back to your own stackoverflow answer that you'd completely forgotten about. It's astonishing how often that happens.
  • user3284707
    user3284707 over 3 years
    This worked for me, along with doing this... stackoverflow.com/a/41988719/3284707
  • Oblivion2000
    Oblivion2000 about 3 years
    For me, I had to ensure that I removed the OPTIONSVerbHandler, otherwise the OWIN Cors solution didn't do anything (code ran, but nothing happened from it).