title: JWT TokenValidationParameters problem with ValidAudiences
body: <p>I'm using JWT in an ASP.NET Core web api (.NET Core 3.1) with Microsoft.AspNetCore.Identity.
  I have two projects set up as follows:</p>
  <p><strong>MyProj.Identity</strong> and <strong>MyProj.Server</strong>.
  I've defined 2 roles: &quot;admin&quot; and &quot;user&quot;. I would like to authorise the calls to MyProj.Server controllers with tokens generated by MyProj.Identity for users in role &quot;user&quot;. I would also like to authorise some calls to MyProj.Identity with tokens generated by MyProj.Identity for users in role &quot;admin&quot;.
  In MyProj.Identity I have the following controller:</p>
  <pre><code>namespace MyProj.Identity.Controllers
  {
      [ApiController]
      [Route(&quot;api/authentication&quot;)]
      public class AuthenticationController : ControllerBase
      {           
          //...
          [HttpPost(&quot;login&quot;)]
          public async Task&lt;IActionResult&gt; Login([FromBody] LoginDto model)
          {
              //...
          }
          
          [Authorize(Roles = UserRoles.Admin)]
          [HttpPost(&quot;register&quot;)]
          public async Task&lt;IActionResult&gt; Register([FromBody] RegistrationInfo registrationInput)
          {
              //...
          }
          
          [Authorize(Roles = UserRoles.Admin)]
          [HttpPost(&quot;register-admin&quot;)]
          public async Task&lt;IActionResult&gt; RegisterAdmin([FromBody] RegistrationInfo registrationInput)
          {
              //...
          }
      }
  }
  </code></pre>
  <p>In MyProj.Server there are controllers like the following:</p>
  <pre><code>namespace MyProj.Server.Controllers
  {
      [Authorize(Roles = UserRoles.User)]
      [ApiController]
      [Route(&quot;api/items&quot;)]
      public class MyController : ControllerBase
      {
          //...
          [HttpGet]
          public async Task&lt;ActionResult&lt;IEnumerable&lt;ItemDto&gt;&gt;&gt; Get()
          {
              //...
          }
          //...
      }
  }
  </code></pre>
  <p>The Startup in both projects has the following configuration</p>
  <p>Startup</p>
  <pre><code>public void ConfigureServices(IServiceCollection services)
  {
      //...
      services.AddAuthentication(options =&gt;
      {
          options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
          options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
      })
  
      // Adding Jwt Bearer  
      .AddJwtBearer(options =&gt;
      {
          options.SaveToken = true;
          options.RequireHttpsMetadata = false;
          options.TokenValidationParameters = new TokenValidationParameters()
          {
              ValidateIssuer = true,
              ValidateAudience = true,
              ValidateIssuerSigningKey = true,
              ValidIssuer = Configuration[&quot;JWT:ValidIssuer&quot;],
              ValidAudiences = Configuration.GetSection(&quot;JWT:ValidAudiences&quot;).Get&lt;string[]&gt;(),
              IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration[&quot;JWT:Secret&quot;]))
          };
          options.Events = new JwtBearerEvents
          {
              OnAuthenticationFailed = context =&gt;
              {
                  if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                  {
                      context.Response.Headers.Add(&quot;Token-Expired&quot;, &quot;true&quot;);
                  }
                  return Task.CompletedTask;
              }
          };
      });
      //...
  }
  </code></pre>
  <p>In the appsettings.json for both projects there is:</p>
  <pre><code>&quot;JWT&quot;: {
      &quot;ValidIssuer&quot;: &quot;http://MyProj.Identity.Url&quot;,
      &quot;ValidAudiences&quot;: [
        &quot;http://MyProj.Identity.Url&quot;,
        &quot;http://MyProj.Server.Url&quot; 
      ],
      &quot;Secret&quot;: &quot;MySecret&quot;,
      &quot;TokenExpiryMinutes&quot;: &quot;120&quot;
    }
  </code></pre>
  <p>The problem I'm having is that when I set the <strong>ValidAudiences</strong> property in the TokenValidationParameters, the token that is generated upon Login doesn't have any &quot;aud&quot; set (inspecting it with <a href="https://jwt.io/" rel="nofollow noreferrer">https://jwt.io/</a>) and authorisation fails as a consequence. If I set the <strong>ValidAudience</strong> property instead (single audience), everything works fine but I'm not able to authorise more than one audience. I tried setting the &quot;ValidAudiences&quot; property manually from a list as well (not from config), but the result was the same. I seem to be missing something with regards to the multiple valid audiences. Any ideas would be appreciated.</p>