title: WebApi Unauthorized (401) on production
body: <p>I have seen several questions and some answers regarding the WebApi 401 unauthorized issue. I still cannot figure out why everything works fine in local environment; however the above error happens on production. </p>
  
  <p>I am posting most of the code logic, so someone can explain where the problem lies and what the solution is. And, please, try to be precise and clear. All the the answers - including this one: <a href="https://stackoverflow.com/questions/25483508/owin-bearer-token-not-working-for-webapi">Owin Bearer Token Not Working for WebApi</a> - are still unclear to me.</p>
  
  <p>As you will notice below, I just use the provided templates, with no much change.</p>
  
  <p>So, here the usual entry in Global.asax.cs:</p>
  
  <pre><code>public class WebApiApplication : System.Web.HttpApplication
  {
      protected void Application_Start()
      {
          AreaRegistration.RegisterAllAreas();
          GlobalConfiguration.Configure(WebApiConfig.Register);
          FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
          RouteConfig.RegisterRoutes(RouteTable.Routes);
          BundleConfig.RegisterBundles(BundleTable.Bundles);
      }
  }
  </code></pre>
  
  <p>Below is the Startup.cs:</p>
  
  <pre><code>public partial class Startup
  {
      public void Configuration(IAppBuilder app)
      {
          ConfigureAuth(app);
      }
  }
  </code></pre>
  
  <p>And here is the Startup.Auth.cs file:</p>
  
  <pre><code>public partial class Startup
  {
      public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
  
      public static string PublicClientId { get; private set; }
  
      // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
      public void ConfigureAuth(IAppBuilder app)
      {
          // Configure the db context and user manager to use a single instance per request
          app.CreatePerOwinContext(ApplicationDbContext.Create);
          app.CreatePerOwinContext&lt;ApplicationUserManager&gt;(ApplicationUserManager.Create);
  
          // Enable the application to use a cookie to store information for the signed in user
          // and to use a cookie to temporarily store information about a user logging in with a third party login provider
          app.UseCookieAuthentication(new CookieAuthenticationOptions());
          app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
  
          // Configure the application for OAuth based flow
          PublicClientId = "self";
          OAuthOptions = new OAuthAuthorizationServerOptions
          {
              TokenEndpointPath = new PathString("/Token"), 
              Provider = new ApplicationOAuthProvider(PublicClientId),
              AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
              AccessTokenExpireTimeSpan = TimeSpan.FromDays(7),
              // In production mode set AllowInsecureHttp = false
              AllowInsecureHttp = bool.Parse(System.Web.Configuration.WebConfigurationManager.AppSettings.Get("Oauth_AllowInsecureHttp"))
          };
  
          // Enable the application to use bearer tokens to authenticate users
          app.UseOAuthBearerTokens(OAuthOptions);
  
          //****************** GOOGLE AUTHENTICATION *******************************************************
          app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
          {
              ClientId = System.Web.Configuration.WebConfigurationManager.AppSettings.Get("Oauth_Google:ClientID"),
              ClientSecret = System.Web.Configuration.WebConfigurationManager.AppSettings.Get("Oauth_Google:ClientSecret")
  
          });
      }
  }
  </code></pre>
  
  <p>Finally, the WebApiConfig:</p>
  
  <pre><code>public static class WebApiConfig
  {
      public static void Register(HttpConfiguration config)
      {
          // Elmah logging...
          config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
  
          // Web API configuration and services
          // Configure Web API to use only bearer token authentication.
          config.SuppressDefaultHostAuthentication();
          config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
  
          // Web API routes
          config.MapHttpAttributeRoutes();
  
          config.Routes.MapHttpRoute(
              name: "DefaultApi",
              routeTemplate: "api/{controller}/{id}",
              defaults: new { id = RouteParameter.Optional }
          );
      config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
      config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
      }
  }
  </code></pre>
  
  <p>As mentioned earlier, everything works fine locally. The 401 (authorized) issue happens only when deployed on remote server. We have tested with Postman, still no luck. The response headers show:
  - Server →Microsoft-IIS/8.5; 
  - WWW-Authenticate →Bearer, Negotiate, NTLM</p>
  
  <p>So, definitely, "Authorization: Bearer SomeTokenBlablablab" should work....</p>
  
  <p>Thank you for your help.</p>