title: ASP.NET Core JWT Bearer Token Custom Validation
body: <p>After a lot of reading, I have found a way to implement a custom JWT bearer token validator as below.</p>
  <p><code>Starup.cs</code>:</p>
  <pre><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
           ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
  {
      loggerFactory.AddConsole(Configuration.GetSection(&quot;Logging&quot;));
      loggerFactory.AddDebug();
          
      app.UseStaticFiles();
          
      app.UseIdentity();
  
      ConfigureAuth(app);
          
      app.UseMvcWithDefaultRoute();            
  }
  
  private void ConfigureAuth(IApplicationBuilder app)
  {
  
      var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection(&quot;TokenAuthentication:SecretKey&quot;).Value));
  
  
      var tokenValidationParameters = new TokenValidationParameters
      {
          // The signing key must match!
          ValidateIssuerSigningKey = true,
          IssuerSigningKey = signingKey,
          // Validate the JWT Issuer (iss) claim
          ValidateIssuer = true,
          ValidIssuer = Configuration.GetSection(&quot;TokenAuthentication:Issuer&quot;).Value,
          // Validate the JWT Audience (aud) claim
          ValidateAudience = true,
          ValidAudience = Configuration.GetSection(&quot;TokenAuthentication:Audience&quot;).Value,
          // Validate the token expiry
          ValidateLifetime = true,
          // If you want to allow a certain amount of clock drift, set that here:
          ClockSkew = TimeSpan.Zero
      };
  
      var jwtBearerOptions = new JwtBearerOptions();
      jwtBearerOptions.AutomaticAuthenticate = true;
      jwtBearerOptions.AutomaticChallenge = true;
      jwtBearerOptions.TokenValidationParameters = tokenValidationParameters;
      jwtBearerOptions.SecurityTokenValidators.Clear();
      //below line adds the custom validator class
      jwtBearerOptions.SecurityTokenValidators.Add(new CustomJwtSecurityTokenHandler());
      app.UseJwtBearerAuthentication(jwtBearerOptions);
      
      var tokenProviderOptions = new TokenProviderOptions
      {
          Path = Configuration.GetSection(&quot;TokenAuthentication:TokenPath&quot;).Value,
          Audience = Configuration.GetSection(&quot;TokenAuthentication:Audience&quot;).Value,
          Issuer = Configuration.GetSection(&quot;TokenAuthentication:Issuer&quot;).Value,
          SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
      };
  
      app.UseMiddleware&lt;TokenProviderMiddleware&gt;(Options.Create(tokenProviderOptions));
  }
  </code></pre>
  <p>Custom validator class:</p>
  <pre><code>public class CustomJwtSecurityTokenHandler : ISecurityTokenValidator
  {
      private int _maxTokenSizeInBytes = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
      private JwtSecurityTokenHandler _tokenHandler;
  
      public CustomJwtSecurityTokenHandler()
      {
          _tokenHandler = new JwtSecurityTokenHandler();
      }
      
      public bool CanValidateToken
      {
          get
          {
              return true;
          }
      }
  
      public int MaximumTokenSizeInBytes
      {
          get
          {
              return _maxTokenSizeInBytes;
          }
  
          set
          {
              _maxTokenSizeInBytes = value;
          }
      }
  
      public bool CanReadToken(string securityToken)
      {
          return _tokenHandler.CanReadToken(securityToken);            
      }
  
      public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
      {
          //How to access HttpContext/IP address from here?
  
          var principal = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);
  
          return principal;
      }
  }
  </code></pre>
  <p>In case of stolen token, I would like to add an additional layer of security to validate that the request is coming from the same client who generated the token.</p>
  <p><strong>Questions:</strong></p>
  <ol>
  <li>Is there any way I can access <code>HttpContext</code> within the <code>CustomJwtSecurityTokenHandler</code> class so that I could add custom validations based on the current client/requestor?</li>
  <li>Is there any other way we can validate the authenticity of the requestor using such method/middleware?</li>
  </ol>