title: CORS error with MSAL, Angular and ASP.NET Core
body: <p>I'm trying to build an ASP.NET Core webapi + Angular website where users can login using Microsoft personal or work or school email. I followed the instructions described here:
  <a href="https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/README.md" rel="nofollow noreferrer">https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-angular/README.md</a></p>
  <p>But encouter this issue,</p>
  <ol>
  <li><p>The angular website load, and the protected component on the home page trigger the login procedure</p>
  </li>
  <li><p>The microsoft web site appear</p>
  </li>
  <li><p>I login</p>
  </li>
  <li><p>The browser load the following url: https://localhost:44321/#id_token=...&amp;state=...</p>
  </li>
  <li><p>The website reload again (for a second time after the signin)</p>
  </li>
  <li><p>And I see the following error</p>
  <p>Access to XMLHttpRequest at 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=...' (redirected from 'https://localhost:44321/Environment/GetUserInfo') from origin 'https://localhost:44321' 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.</p>
  </li>
  </ol>
  <p>when debugging locally with Visual Studio 2019 16.4.2 and chrome 79.0.3945.88</p>
  <p>Any idea?<br/>
  <strong>Thanks</strong></p>
  <p>I've created my project using</p>
  <pre><code>dotnet new angular -o myapp
  </code></pre>
  <p>And created an app registration in Azure.Portal<br/>
  Authentication with following redirect URI</p>
  <ul>
  <li>https://localhost:44321/signin-microsoft</li>
  <li>https://login.microsoftonline.com/</li>
  <li>http://localhost:30662/</li>
  <li>https://localhost:44321/signin-oidc</li>
  <li>https://localhost:44321/</li>
  </ul>
  <p>Checked all the &quot;Suggested Redirect URIs for public clients&quot;<br/>
  Logout URL: https://localhost:44321/signout-callback-oidc<br/>
  Implicit grant: Access tokens and ID tokens<br/>
  Live SDK support: Yes<br/>
  Default client type: No<br/></p>
  <p>Certificate &amp; Secret<br/>
  I've created a client secret, becaused I tried to use Microsoft provider (see commented code below) then tried with AzureAd</p>
  <p>API Permission<br/>
  Microsoft.Graph User.Read</p>
  <p>Expose an API<br/>
  Scope = [Application ID URI]/access_as_user, Admins Only<br/>
  Client application = [CLIENT_ID_FROM_AZURE_PORTAL], scope above</p>
  <p><strong>Server side</strong><br/>
  <strong>appsettings.json</strong></p>
  <pre><code> &quot;AzureAd&quot;: {
      &quot;Instance&quot;: &quot;https://login.microsoftonline.com/&quot;,
      &quot;Domain&quot;: &quot;[Application ID URI]&quot;,
      &quot;ClientId&quot;: &quot;[CLIENT_ID_FROM_AZURE_PORTAL]&quot;,
      &quot;TenantId&quot;: &quot;common&quot;,
      &quot;CallbackPath&quot;: &quot;/signin-oidc&quot;
    },
  </code></pre>
  <p><strong>Startup.cs</strong><br/></p>
  <pre><code>public void ConfigureServices(IServiceCollection services)
  {
    services.AddCors(options =&gt;
    {
      options.AddPolicy(&quot;AllowAllOrigins&quot;,
          builder =&gt;
          {
            builder
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowAnyOrigin();
          });
    });
  
    services.Configure&lt;CookiePolicyOptions&gt;(options =&gt;
    {
      // This lambda determines whether user consent for non-essential cookies is needed for a given request.
      options.CheckConsentNeeded = context =&gt; true;
      options.MinimumSameSitePolicy = SameSiteMode.None;
    });
  
    // In production, the Angular files will be served from this directory
    services.AddSpaStaticFiles(configuration =&gt;
    {
      configuration.RootPath = &quot;ClientApp/dist&quot;;
    });
  
    //services
    //  .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    //  .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    //  .AddMicrosoftAccount(microsoftOptions =&gt;
    //{
    //  microsoftOptions.ClientId = &quot;[CLIENT_ID_FROM_AZURE_PORTAL]&quot;;
    //  microsoftOptions.ClientSecret = &quot;[CLIENT_SECRET_FROM_AZURE_PORTAL]&quot;;
    //});
  
    services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
      .AddAzureAD(options =&gt; Configuration.Bind(&quot;AzureAd&quot;, options));
  
    services.Configure&lt;OpenIdConnectOptions&gt;(AzureADDefaults.OpenIdScheme, options =&gt;
    {
      options.Authority = options.Authority + &quot;/v2.0/&quot;;
      options.TokenValidationParameters.ValidateIssuer = false;
    });
  
    services.AddControllers(options =&gt;
    {
      var policy = new AuthorizationPolicyBuilder()
                      .RequireAuthenticatedUser()
                      .Build();
      options.Filters.Add(new AuthorizeFilter(policy));
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  }
  
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  {
    app.UseCors(&quot;AllowAllOrigins&quot;);
  
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }
    else
    {
      app.UseExceptionHandler(&quot;/Error&quot;);
      app.UseHsts();
    }
  
    app.UseHttpsRedirection();
    app.UseCookiePolicy();
    app.UseStaticFiles();
    if (!env.IsDevelopment())
    {
      app.UseSpaStaticFiles();
    }
  
    app.UseRouting();
  
    app.UseAuthentication();
    app.UseAuthorization();
  
    app.UseEndpoints(endpoints =&gt;
    {
      endpoints.MapControllers();
    });
  
    app.UseSpa(spa =&gt;
    {
      spa.Options.SourcePath = &quot;ClientApp&quot;;
  
      if (env.IsDevelopment())
      {
        spa.UseAngularCliServer(npmScript: &quot;start&quot;);
      }
    });
  }
  </code></pre>
  <p><strong>Client side</strong><br/>
  <strong>app.module.ts</strong></p>
  <pre><code>...
  import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
  import { MsalModule, MsalGuard, MsalInterceptor } from '@azure/msal-angular';
  ...
  export const protectedResourceMap: [string, string[]][] = [
    ['https://localhost:44321/Environment/GetUserInfo', ['[Application ID URI]/access_as_user']],
    ['https://localhost:44321/api/Environment/GetUserInfo', ['[Application ID URI]/access_as_user']],
    ['https://graph.microsoft.com/v1.0/me', ['user.read']],
    ['https://login.microsoftonline.com/common', ['user.read']]
  ];
  
  @NgModule({
    declarations: [
      AppComponent,
      NavMenuComponent,
      HomeComponent,
      CounterComponent,
      EntitySignoffComponent
    ],
    imports: [
      BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
      HttpClientModule,
      FormsModule,
      AgGridModule.withComponents([]),
      MsalModule.forRoot({
        clientID: [CLIENT_ID_FROM_AZURE_PORTAL],
        authority: &quot;https://login.microsoftonline.com/common&quot;,
        redirectUri: &quot;https://localhost:44321/&quot;,
        validateAuthority: true,
        cacheLocation: &quot;localStorage&quot;,
        storeAuthStateInCookie: false, // dynamically set to true when IE11
        postLogoutRedirectUri: &quot;https://localhost:44321/&quot;,
        navigateToLoginRequestUrl: true,
        popUp: false,
        unprotectedResources: [ &quot;https://login.microsoftonline.com/common&quot; ],
        protectedResourceMap: protectedResourceMap
      }
      ),
      RouterModule.forRoot([
        { path: '', component: HomeComponent, pathMatch: 'full', canActivate: [MsalGuard] }
        { path: 'counter', component: CounterComponent, canActivate: [MsalGuard] },
      ])
    ],
    providers: [NavMenuComponent, { provide: HTTP_INTERCEPTORS, useClass: MsalInterceptor, multi: true }],
  </code></pre>
  <p><strong>package.json</strong></p>
  <pre><code>{
    &quot;name&quot;: &quot;myapp&quot;,
    &quot;version&quot;: &quot;0.0.0&quot;,
    &quot;scripts&quot;: {
      &quot;ng&quot;: &quot;ng&quot;,
      &quot;start&quot;: &quot;ng serve&quot;,
      &quot;build&quot;: &quot;ng build&quot;,
      &quot;build:ssr&quot;: &quot;ng run myapp:server:dev&quot;,
      &quot;test&quot;: &quot;ng test&quot;,
      &quot;lint&quot;: &quot;ng lint&quot;,
      &quot;e2e&quot;: &quot;ng e2e&quot;
    },
    &quot;private&quot;: true,
    &quot;dependencies&quot;: {
      &quot;@angular/animations&quot;: &quot;8.2.14&quot;,
      &quot;@angular/common&quot;: &quot;^8.2.14&quot;,
      &quot;@angular/compiler&quot;: &quot;8.2.14&quot;,
      &quot;@angular/core&quot;: &quot;^8.2.14&quot;,
      &quot;@angular/forms&quot;: &quot;8.2.14&quot;,
      &quot;@angular/platform-browser&quot;: &quot;8.2.14&quot;,
      &quot;@angular/platform-browser-dynamic&quot;: &quot;8.2.14&quot;,
      &quot;@angular/platform-server&quot;: &quot;8.2.14&quot;,
      &quot;@angular/router&quot;: &quot;8.2.14&quot;,
      &quot;@azure/msal-angular&quot;: &quot;^0.1.4&quot;,
      &quot;@nguniversal/module-map-ngfactory-loader&quot;: &quot;8.2.6&quot;,
      &quot;aspnet-prerendering&quot;: &quot;^3.0.1&quot;,
      &quot;bootstrap&quot;: &quot;^4.4.1&quot;,
      &quot;core-js&quot;: &quot;^3.6.1&quot;,
      &quot;jquery&quot;: &quot;3.4.1&quot;,
      &quot;oidc-client&quot;: &quot;^1.10.1&quot;,
      &quot;popper.js&quot;: &quot;^1.16.0&quot;,
      &quot;rxjs&quot;: &quot;^6.5.4&quot;,
      &quot;rxjs-compat&quot;: &quot;^6.5.4&quot;,
      &quot;zone.js&quot;: &quot;0.10.2&quot;
    },
    &quot;devDependencies&quot;: {
      &quot;@angular-devkit/build-angular&quot;: &quot;^0.803.21&quot;,
      &quot;@angular/cli&quot;: &quot;8.3.21&quot;,
      &quot;@angular/compiler-cli&quot;: &quot;8.2.14&quot;,
      &quot;@angular/language-service&quot;: &quot;8.2.14&quot;,
      &quot;@types/jasmine&quot;: &quot;^3.5.0&quot;,
      &quot;@types/jasminewd2&quot;: &quot;~2.0.8&quot;,
      &quot;@types/node&quot;: &quot;~13.1.2&quot;,
      &quot;codelyzer&quot;: &quot;^5.2.1&quot;,
      &quot;jasmine-core&quot;: &quot;~3.5.0&quot;,
      &quot;jasmine-spec-reporter&quot;: &quot;~4.2.1&quot;,
      &quot;karma&quot;: &quot;^4.4.1&quot;,
      &quot;karma-chrome-launcher&quot;: &quot;~3.1.0&quot;,
      &quot;karma-coverage-istanbul-reporter&quot;: &quot;^2.1.1&quot;,
      &quot;karma-jasmine&quot;: &quot;~2.0.1&quot;,
      &quot;karma-jasmine-html-reporter&quot;: &quot;^1.5.1&quot;,
      &quot;typescript&quot;: &quot;3.5.3&quot;
    },
    &quot;optionalDependencies&quot;: {
      &quot;node-sass&quot;: &quot;^4.13.0&quot;,
      &quot;protractor&quot;: &quot;~5.4.2&quot;,
      &quot;ts-node&quot;: &quot;~8.5.4&quot;,
      &quot;tslint&quot;: &quot;~5.20.1&quot;
    }
  }
  </code></pre>
  <p><a href="https://i.stack.imgur.com/WA8zu.png" rel="nofollow noreferrer">Error in Chrome after login</a></p>