title: How to capture a SecurityTokenExpiredException in OWIN middleware?
body: <p>I have a Web API with OWIN that uses <code>JwtBearerAuthenticationOptions</code> (.Net Framework 4.5.2) to validate authentication tokens.</p>
  
  <p>While following <a href="https://www.blinkingcaret.com/2018/05/30/refresh-tokens-in-asp-net-core-web-api/" rel="nofollow noreferrer">this excellent article</a> by Rui Figueiredo in order to add a Refresh Token ability to the API, it seems I don't have <code>JwtBearerEvents</code> in OWIN. E.g. This code works for me in ASP.NET Core (in ConfigureServices):</p>
  
  <pre><code>services.AddAuthentication(x =&gt;
  {
      x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
      x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
  })
  .AddJwtBearer(x =&gt;
  {
      x.RequireHttpsMetadata = false;
      x.SaveToken = true;
      x.TokenValidationParameters = GetDefaultValidationParameters();
      x.Events = new JwtBearerEvents
      {
          OnAuthenticationFailed = context =&gt;
          {
              if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
              {
                  context.Response.Headers.Add("Token-Expired", "true");
              }
              return Task.CompletedTask;
          }
      };
  });
  </code></pre>
  
  <p>I can't seem to grasp how to achieve the same using the OWIN pipeline. What I've tried is inserting a middleware in ConfigureAuth:</p>
  
  <pre><code>private static void ConfigureAuth(IAppBuilder pApp)
  {
      pApp.Use(async (context, next) =&gt;
      {
          try
          {
              await next.Invoke();
          }
          catch (SecurityTokenExpiredException)
          {
              context.Response.Headers.Add("Token - Expired", new[] { "true" });
              throw;
          }
      });
      var issuer = "issuer";
      var audience = "all";
      var key = Encoding.ASCII.GetBytes("MySecretKey");
      pApp.UseJwtBearerAuthentication(
          new JwtBearerAuthenticationOptions
          {
              AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
              AllowedAudiences = new[] { audience },
              IssuerSecurityKeyProviders = new IIssuerSecurityKeyProvider[]
              {
                  new SymmetricKeyIssuerSecurityKeyProvider(issuer, key)
              },
              TokenValidationParameters = tokenValidationParameters,
              TokenHandler = new CustomJWTTokenHandler()
          });
  }
  </code></pre>
  
  <p>But to no avail. The 401 status comes without the Token-Expired header in this case.</p>
  
  <p>Does anybody have any pointers on how to do this properly in Katana?</p>