title: Why CORS error "Response to preflight request doesn't pass access control check"?
body: <p>I'm using <strong>ASP.NET Web API with OAuth authorization</strong> in my project.</p>
  
  <p>I have tried to decouple every tier in the solution using best practices.
  I have a web project which contains AngularJS files and other resources which is uploaded on www.example.com and I have another project which is protected backend web api controllers and server side stuff which is uploaded on api.example.com</p>
  
  <p>It all works fine in localhost. when I publish this to production server request for "/token" is successful but requesting any action in any controller in the back-end api returns this error:
  <strong>"Access to XMLHttpRequest at '<a href="http://api.example.com/someRoute" rel="nofollow noreferrer">http://api.example.com/someRoute</a>' from origin '<a href="http://www.example.com" rel="nofollow noreferrer">http://www.example.com</a>' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.".</strong></p>
  
  <p>I searched almost any active link for similar error on the internet and no answers yet for me!</p>
  
  <p>I paste some of my code here from the back-end API so you can understand my approach better.</p>
  
  <pre><code>public partial class Startup
  {
      public void Configuration(IAppBuilder app)
      {
  
          HttpConfiguration httpConfig = new HttpConfiguration();
  
          UnityConfig.Register(httpConfig);
  
          ConfigureAuth(app);
  
          WebApiConfig.Register(httpConfig);
  
          app.UseWebApi(httpConfig);
  
          #region AutoMapper Init
          DtoMapping.Map();
          #endregion
      }
  }
  
  
  public void ConfigureAuth(IAppBuilder app)
      {
          // Configure the auth context, user manager and signin manager to use a single instance per request
          app.CreatePerOwinContext(AuthContext.Create);
          app.CreatePerOwinContext&lt;ApplicationUserManager&gt;(ApplicationUserManager.Create);
          app.CreatePerOwinContext&lt;ApplicationSignInManager&gt;(ApplicationSignInManager.Create);
  
          OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
          {
              //remove this line on production
              AllowInsecureHttp = true,
              TokenEndpointPath = new PathString("/token"),
              AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
              Provider = new SimpleAuthorizationServerProvider()
          };
  
          // Token Generation
          app.UseOAuthBearerTokens(OAuthServerOptions);
          app.UseOAuthAuthorizationServer(OAuthServerOptions);
          app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
      }
  
  public class WebApiConfig
  {
      public static void Register(HttpConfiguration config)
      {
          EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");
          config.EnableCors(cors);
  
          config.MapHttpAttributeRoutes();
  
          //...
      }
  }
  
  [EnableCors("*", "*", "*")]
  public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
  {
      public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
      {
          context.Validated();
          return Task.FromResult&lt;object&gt;(null);
      }
  
      public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
      {
          var identity = new ClaimsIdentity(context.Options.AuthenticationType);
          context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
  
          IList&lt;string&gt; roleNames;
          using (var _repo = new IdentityRepository())
          {
              var user = await _repo.FindUserAsync(context.UserName, context.Password);
              if (user == null)
              {
                  context.SetError("invalid_grant", "username or password is invalid.");
                  context.Rejected();
                  return;
              }
  
              roleNames = await _repo.GetRolesForUserAsync(user.Id);
          }
  
          identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
          foreach (var roleName in roleNames)
          {
              identity.AddClaim(new Claim(ClaimTypes.Role, roleName));
          }
  
          var props = new AuthenticationProperties(new Dictionary&lt;string, string&gt;
              {
                  {
                      "userName", context.UserName
                  }
              });
  
          var ticket = new AuthenticationTicket(identity, props);
          context.Validated(ticket);
  
      }
  }
  </code></pre>
  
  <p>So, Can anyone please help me?</p>
  
  <p>Thank you for your time.</p>