title: Azure AD Multi Tenant ,.Net Core Web API with JWT Token
body: <p>So I raised this question <a href="https://stackoverflow.com/questions/60712602/azure-ad-multi-tenant-net-core-web-api-with-msalmicrosoft-authentication-liba">Azure AD Multi Tenant ,.Net Core Web API with MSAL(Microsoft Authentication Libary)</a> which showed me how to turn on the error output. </p>
  
  <p>Why would I be getting this now with my token, at a guess is the <strong>aud</strong> right and the <strong>iss</strong> for a multi tenant ad token?</p>
  
  <pre><code>AuthenticationFailed: IDX10511: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.X509SecurityKey, KeyId: 'YMELHT0gvb0mxoSDoYfomjqfjYU', InternalId: '2c34a300-21bb-4eb1-b3b9-1944f1be7470'. , KeyId: YMELHT0gvb0mxoSDoYfomjqfjYU
  '. 
  kid: 'YMELHT0gvb0mxoSDoYfomjqfjYU'. 
  Exceptions caught:
   ''.
  token: '
  {
      "alg": "RS256",
      "typ": "JWT",
      "nonce": "bWqlNum32nkLGFA4s5lE83AEZ6hRUzqi4r4-3JMZLdw",
      "x5t": "YMELHT0gvb0mxoSDoYfomjqfjYU",
      "kid": "YMELHT0gvb0mxoSDoYfomjqfjYU"
  }
  .{
      "aud": "00000003-0000-0000-c000-000000000000",
      "iss": "https://sts.windows.net/abc60396-1ed0-4fa3-a3d0-597adf1366a5/",
      "iat": 1584438416,
      "nbf": 1584438416,
      "exp": 1584442316,
      "acct": 0,
      "acr": "1",
      "aio": "42NgYNh7TvzDvOILBsl/7E+U+vxP6y5rmJERnny04o5ZM2vJjmwA",
      "amr": ["pwd"],
      "app_displayname": "AzureAdTest",
      "appid": "A134d6c8-8078-2924-9e90-98cef862eb9a",
      "appidacr": "0",
      "family_name": "Bob",
      "given_name": "Bob",
      "ipaddr": "111.111.124.18",
      "name": "Bob Powell",
      "oid": "5b2dfaea-41fb-4a76-93da-6b4c04041f4d",
      "platf": "3",
      "puid": "10032000A35A0EE1",
      "scp": "openid profile User.Read email",
      "sub": "NM4nVqUfyC-6pF66I1Wef8Bvl7rhnpB_UBv7fX-qMHU",
      "tid": "abc60396-1ed0-4fa3-a3d0-597adf1366a5",
      "unique_name": "a@b.onmicrosoft.com",
      "upn": "a@b.onmicrosoft.com",
      "uti": "-mwXtFoS1kGJjorQqzI0AA",
      "ver": "1.0",
      "xms_st": {
          "sub": "p7nf6_rRkoqINUHy3cl_qRQ2F-DaCfFwQgy6gTQv_QY"
      },
      "xms_tcdt": 1583932579
  }
  '.
  </code></pre>
  
  <p>My previous question was:</p>
  
  <p>I believe I have the Microsoft Authentication Library (MSAL) JavaScript pulling back a JWT token, using azure AD multi tenant with the following config.
  Based of this link <a href="https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant" rel="noreferrer">https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant</a>. I believe I only need the following two values.</p>
  
  <pre><code>clientId: "A134d6c8-8078-2924-9e90-98cef862eb9a" // this would be the app registrations client id(application)
  authority: "https://login.microsoftonline.com/common"
  </code></pre>
  
  <p>How then can I configure a .net core 3 web api that can handle this JWT token and authenticate [Authorize] endpoints by me passing the Authorization: Bearer header.</p>
  
  <p>I currently get this error in the response which is not very helpful!</p>
  
  <pre><code>AuthenticationFailed: IDX10511: Signature validation failed. Keys tried: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. 
  kid: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. 
  Exceptions caught:
   '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
  token: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
  </code></pre>
  
  <p>The Startup.cs code is as follows</p>
  
  <pre><code>using System.Text;
  using System.Threading.Tasks;
  using Microsoft.AspNetCore.Authentication.JwtBearer;
  using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Hosting;
  using Microsoft.IdentityModel.Tokens;
  
  namespace MultiTenantApi
  {
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
  
              Configuration = configuration;
          }
  
          public IConfiguration 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(x =&gt;
              {
                  x.AddDefaultPolicy(cfg =&gt;
                  {
                      cfg.AllowAnyOrigin()
                          .AllowAnyHeader()
                          .AllowAnyMethod();
                  });
              });
  
              services.AddAuthentication(cfg =&gt;
                  {
                      cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                      cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                  })
                  .AddJwtBearer(opt =&gt;
                  {
                      opt.Authority = "https://login.microsoftonline.com/common";
                      opt.Audience = "api://A134d6c8-8078-2924-9e90-98cef862eb9a"; // Set this to the App ID URL for the web API, which you created when you registered the web API with Azure AD.
                      opt.TokenValidationParameters = new TokenValidationParameters
                      {
                          ValidateIssuer = false
                      };
                      opt.Events = new JwtBearerEvents()
                      {
                          OnAuthenticationFailed = AuthenticationFailed
                      };
                  });
  
              services.AddControllers();
  
          }
  
          private Task AuthenticationFailed(AuthenticationFailedContext arg)
          {
              // For debugging purposes only!
              var s = $"AuthenticationFailed: {arg.Exception.Message}";
              arg.Response.ContentLength = s.Length;
              arg.Response.Body.WriteAsync(Encoding.UTF8.GetBytes(s), 0, s.Length);
              return Task.FromResult(0);
          }
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
  
              app.UseHttpsRedirection();
  
              app.UseStaticFiles(); // Added
  
              app.UseRouting();
              app.UseCors(); //Added
  
              app.UseAuthentication();
              app.UseAuthorization();
  
              app.UseEndpoints(endpoints =&gt;
              {
                  endpoints.MapControllers();
              });
  
          }
  
      }
  }
  </code></pre>