title: When including Bearer in request I get CORS error, IdentityServer4, Api, angular
body: <p>I am having trouble to getting data after I have logged in.</p>
  
  <p>I am using IdentityServer4 with a WebApi. Everything is working as long as I dont send any authorization berarer. I am using the authorizationinterceptor from Damien Bod.</p>
  
  <p>When I am sending the bearer I get this back:</p>
  
  <blockquote>
    <p>GET <a href="https://localhost:44373/api/pages/10" rel="nofollow">https://localhost:44373/api/pages/10</a>  10:1 XMLHttpRequest cannot
    load <a href="https://localhost:44373/api/pages/10" rel="nofollow">https://localhost:44373/api/pages/10</a>. No
    'Access-Control-Allow-Origin' header is present on the requested
    resource. Origin '<a href="http://localhost:3000" rel="nofollow">http://localhost:3000</a>' is therefore not allowed
    access. The response had HTTP status code 500.</p>
  </blockquote>
  
  <p>This works as long as I don't add the Authorization header to the http request.</p>
  
  <p>I am using the IdentityServer sample found here:
  <a href="https://github.com/IdentityServer/IdentityServer4.Samples/tree/dev/MVC%20and%20API/src" rel="nofollow">https://github.com/IdentityServer/IdentityServer4.Samples/tree/dev/MVC%20and%20API/src</a></p>
  
  <p>And both the security service and authorization interceptor found here:
  <a href="https://github.com/damienbod/AspNet5IdentityServerAngularImplicitFlow" rel="nofollow">https://github.com/damienbod/AspNet5IdentityServerAngularImplicitFlow</a></p>
  
  <p>So the problem is after I have logged in and trying to retrieve data from API, I get the above error.</p>
  
  <p>API - Startup.cs</p>
  
  <pre><code>public class Startup
  {
      public Startup(IHostingEnvironment env)
      {
          var builder = new ConfigurationBuilder()
              .SetBasePath(env.ContentRootPath)
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
  
          if (env.IsEnvironment("Development"))
          {
              // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
              builder.AddApplicationInsightsSettings(developerMode: true);
          }
  
          builder.AddEnvironmentVariables();
          Configuration = builder.Build();
      }
  
      public IConfigurationRoot Configuration { get; }
  
      // This method gets called by the runtime. Use this method to add services to the container
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddCors();
  
          //services.AddCors(options =&gt; options.AddPolicy("AllowAll", p =&gt; p.AllowAnyOrigin()
          //                                                            .AllowAnyMethod()
          //                                                             .AllowAnyHeader()));
  
          //var policy = new Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy();
  
          //policy.Headers.Add("*");
          //policy.Methods.Add("*");
          //policy.Origins.Add("*");
          //policy.SupportsCredentials = true;
  
          //services.AddCors(x =&gt; x.AddPolicy("AllowAll", policy));
  
          services.AddEntityFramework()
              .AddEntityFrameworkSqlServer()
              .AddDbContext&lt;AsklepiosContext&gt;(options =&gt;               
                  options.UseSqlServer(@"Server = .\SQLEXPRESS; Trusted_Connection = true; Database = AsklepiosTrunk; MultipleActiveResultSets = true;"));
  
          // Add framework services.
          services.AddApplicationInsightsTelemetry(Configuration);
  
          var guestPolicy = new AuthorizationPolicyBuilder()
              .RequireAuthenticatedUser()
              .RequireClaim("scope", "api1")
              .Build();
  
          services.AddMvc(options =&gt;
          {
              options.Filters.Add(new AuthorizeFilter(guestPolicy));
          });
  
          //DI
          // some services here .. 
  
  
      }
  
      // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
      public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
      {
          loggerFactory.AddConsole(Configuration.GetSection("Logging"));
          loggerFactory.AddDebug();
  
          app.UseStaticFiles();
  
          app.UseApplicationInsightsRequestTelemetry();
  
          app.UseApplicationInsightsExceptionTelemetry();
  
          //app.UseCors("AllowAll");
  
          //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary&lt;string, string&gt;();
  
          //var jwtBearerOptions = new JwtBearerOptions()
          //{
          //    Authority = "https://localhost:44301",
          //    Audience = "https://localhost:44301/resources",
          //    AutomaticAuthenticate = true,
  
          //    // required if you want to return a 403 and not a 401 for forbidden responses
          //    AutomaticChallenge = true
          //};
  
          //app.UseJwtBearerAuthentication(jwtBearerOptions);
  
          //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary&lt;string, string&gt;();
  
          //var jwtBearerOptions = new JwtBearerOptions()
          //{
          //    Authority = "https://localhost:44302",
          //    Audience = "https://localhost:44302/resources",
          //    AutomaticAuthenticate = true,
  
          //    // required if you want to return a 403 and not a 401 for forbidden responses
          //    AutomaticChallenge = true,
          //};
  
          //app.UseJwtBearerAuthentication(jwtBearerOptions);
  
          //JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
  
          app.UseCors("AllowAll");
  
          app.UseCors(policy =&gt;
          {
              policy.WithOrigins(
                  "http://localhost:3000");
  
              policy.AllowAnyHeader();
              policy.AllowAnyMethod();
          });
  
  
          JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
  
          app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
          {
              Authority = "https://localhost:44301",
              RequireHttpsMetadata = false,
  
              ScopeName = "api1",
              AutomaticAuthenticate = true
          });
  
          //app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
          //{
          //    Authority = "https://localhost:44301",
          //    RequireHttpsMetadata = false,
  
          //    ScopeName = "dataEventRecords",
          //    AutomaticAuthenticate = true
          //});
  
          app.UseMvc();
      }
  }
  </code></pre>
  
  <p>AuthorizationInterceptor.ts</p>
  
  <pre><code>import { urls } from "../constants";
  
  class AuthorizationInterceptor {
  private static _instance: AuthorizationInterceptor;
  private baseUrl: string;
  
  public static Factory($q: angular.IQService, localStorageService, $window) {
      AuthorizationInterceptor._instance = new AuthorizationInterceptor($q, localStorageService, $window);
      return AuthorizationInterceptor._instance;
  }
  
  constructor(private $q: angular.IQService, private localStorageService, private $window) {
      console.log("AuthorizationInterceptor created");
  }
  
  public request(requestSuccess) {
      const self = AuthorizationInterceptor._instance;
      requestSuccess.headers = requestSuccess.headers || {};
  
          if (self.localStorageService.get("authorizationData") !== null &amp;&amp;
              self.localStorageService.get("authorizationData") !== "") {
              // when it adds this header i get CORS Error
              requestSuccess.headers.Authorization = "Bearer " + self.localStorageService.get("authorizationData");
          }
  
          return requestSuccess || self.$q.when(requestSuccess);
  }
  
  
  public responseError(responseFailure) {
      const self = AuthorizationInterceptor._instance;
      console.log("console.log(responseFailure);");
      console.log(responseFailure);
  
      if (responseFailure.status === 403) {
          alert("forbidden");
          self.$window.location = "https://localhost:44389/forbidden";
          self.$window.href = "forbidden";
  
      } else if (responseFailure.status === 401) {
  
          alert("unauthorized");
          self.localStorageService.set("authorizationData", "");
      }
  
      return self.$q.reject(responseFailure);
  }
  }
  
  export default AuthorizationInterceptor;
  </code></pre>
  
  <p>SecurityService.ts</p>
  
  <pre><code>import DataService from "./dataservice";
  import { urls } from "../constants";
  
  class SecurityService {
  private baseUrl: string;
  private isAuthorized: boolean = false;
  private hasAdminRole: boolean = false;
  
  constructor(private $http, private $log, private $q, private $rootScope, private $window, private $state,
      private localStorageService, private $stateParams) {
      this.baseUrl = `${urls.baseApiUrl}`;
      console.log("return url: " + this.$stateParams.returnurl);
      $log.info("SecurityService called");
  
      // what to put this ?
      this.$rootScope.IsAuthorized = false;
      this.$rootScope.HasAdminRole = false;
  }
  
  public resetAuthorizationData() {
      this.localStorageService.set("authorizationData", "");
      this.localStorageService.set("authorizationDataIdToken", "");
      this.$rootScope.IsAuthorized = false;
      this.$rootScope.HasAdminRole = false;
  }
  
  public setAuthorizationData(token, id_token) {
      if (this.localStorageService.get("authorizationData") !== "") {
          this.localStorageService.set("authorizationData", "");
      }
  
      this.localStorageService.set("authorizationData", token);
      this.localStorageService.set("authorizationDataIdToken", id_token);
      this.$rootScope.IsAuthorized = true;
  
      let data: any = this.getDataFromToken(token);
      if (data.role !== undefined) {
          for (let i = 0; i &lt; data.role.length; i++) {
              if (data.role[i] === "dataEventRecords.admin") {
                  this.$rootScope.HasAdminRole = true;
              }
          }
      }
  }
  
   public authorize() {
      console.log("AuthorizedController time to log on");
  
      // GET /authorize?
      // response_type=code%20id_token
      // &amp;client_id=s6BhdRkqt3
      // &amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
      // &amp;scope=openid%20profile%data
      // &amp;nonce=n-0S6_WzA2Mj
      // &amp;state=af0ifjsldkj HTTP/1.1
  
      const authorizationUrl = "https://localhost:44302/connect/authorize";
      const client_id = "angularclient";
      const redirect_uri = "http://localhost:3000/authorized";
      const response_type = "id_token token";
      const scope = "openid profile api1";
      const nonce = "N" + Math.random() + "" + Date.now();
      const state = Date.now() + "" + Math.random();
  
      this.localStorageService.set("authNonce", nonce);
      this.localStorageService.set("authStateControl", state);
      console.log("AuthorizedController created. adding myautostate: " + this.localStorageService.get("authStateControl"));
  
      const url =
          authorizationUrl + "?" +
          "response_type=" + encodeURI(response_type) + "&amp;" +
          "client_id=" + encodeURI(client_id) + "&amp;" +
          "redirect_uri=" + encodeURI(redirect_uri) + "&amp;" +
          "scope=" + encodeURI(scope) + "&amp;" +
          "nonce=" + encodeURI(nonce) + "&amp;" +
          "state=" + encodeURI(state);
  
      this.$window.location = url;
  }
  
  public doAuthorization() {
      this.resetAuthorizationData();
      if (this.$window.location.hash) {
          this.authorizeCallback();
      } else {
          this.authorize();
      }
  }
  
  public logoff() {
      // var id_token = localStorageService.get("authorizationDataIdToken");
      // var authorizationUrl = 'https://localhost:44330/connect/endsession';
      // var id_token_hint = id_token;
      // var post_logout_redirect_uri = 'https://localhost:44347/unauthorized.html';
      // var state = Date.now() + "" + Math.random();
  
      // var url =
      //    authorizationUrl + "?" +
      //    "id_token_hint=" + id_token_hint + "&amp;" +
      //    "post_logout_redirect_uri=" + encodeURI(post_logout_redirect_uri) + "&amp;" +
      //    "state=" + encodeURI(state);
  
      // ResetAuthorizationData();
      // $window.location = url;
  
      // 19.02.2106: temp until connect/endsession is implemented in IdentityServer4 NOT A PROPER SOLUTION!
      this.resetAuthorizationData();
      this.$window.location = "https://localhost:44389/unauthorized.html";
  }
  
  private urlBase64Decode(str) {
      let output = str.replace("-", "+").replace("_", "/");
          switch (output.length % 4) {
              case 0:
                  break;
              case 2:
                  output += "==";
                  break;
              case 3:
                  output += "=";
                  break;
              default:
                  throw "Illegal base64url string!";
          }
          return window.atob(output);
  }
  
  private getDataFromToken(token) {
      let data = {};
      if (typeof token !== "undefined") {
          let encoded = token.split(".")[1];
          data = JSON.parse(this.urlBase64Decode(encoded));
      }
      return data;
  }
  
  private authorizeCallback() {
      console.log("AuthorizedController created, has hash");
      let hash = window.location.hash.substr(1);
  
      let result: any = hash.split("&amp;").reduce(function (result2, item) {
          let parts = item.split("=");
          result2[parts[0]] = parts[1];
          return result2;
      }, {});
  
      let token = "";
      let id_token = "";
      let authResponseIsValid = false;
      if (!result.error) {
  
          if (result.state !== this.localStorageService.get("authStateControl")) {
              console.log("AuthorizedCallback incorrect state");
          } else {
  
              token = result.access_token;
              id_token = result.id_token;
  
              let dataIdToken: any = this.getDataFromToken(id_token);
              console.log(dataIdToken);
  
              // validate nonce
              if (dataIdToken.nonce !== this.localStorageService.get("authNonce")) {
                  console.log("AuthorizedCallback incorrect nonce");
              } else {
                  this.localStorageService.set("authNonce", "");
                  this.localStorageService.set("authStateControl", "");
  
                  authResponseIsValid = true;
                  console.log("AuthorizedCallback state and nonce validated, returning access token");
              }
          }
      }
  
      if (authResponseIsValid) {
          this.setAuthorizationData(token, id_token);
          console.log(this.localStorageService.get("authorizationData"));
  
          this.$state.go("overviewindex");
      } else {
          this.resetAuthorizationData();
          this.$state.go("unauthorized");
      }
  }
  }
  
  SecurityService.$inject = ["$http", "$log", "$q", "$rootScope", "$window",      "$state", "localStorageService", "$stateParams"];
  export default SecurityService;
  </code></pre>