Home > OS >  JwtBearerEvents.OnAuthenticationFailed not being called...sometimes
JwtBearerEvents.OnAuthenticationFailed not being called...sometimes

Time:01-17

I have an odd problem. I'm new to JWT authentication so it's probably something I'm doing wrong. I'm testing out the Refresh Token mechanism and it works sometimes but not others because sometimes the JwtBearerEvents.OnAuthenticationFailed event does not fire.

I'm using C# (.NET 7) to build an ASPNET Core WebAPI.

Essentially:

  1. On log in (via an AJAX call) I create a JWT token (expires after 10 seconds) and a refresh token (expires after 10 days) and send each back to the client in a cookie.
  2. Chrome correctly lists both the JWT token and the Refresh Token cookies.
  3. I make further (valid) GET requests via AJAX to the API methods which process and return successfully.
  4. If I make a request just after (but within a second of) the expiry time of the JWT token then the JWT cookie is sent to the API, fails validation and the OnAuthenticationFailed event fires.
  5. The Refresh Token mechanism does its thing and the JWT token and Refresh Token are successfully refreshed. Chrome shows the updated cookies correctly. All brilliant so far.
  6. I make further (valid) GET requests via AJAX to the API methods which process and return successfully.
  7. But...if I make a request a bit longer after the expiry time of the JWT token (only a second or 2 difference to Step 4.) then the JWT cookie is deleted by Chrome and is not sent, so the token validation never occurs, the OnAuthenticationFailed event DOES NOT fire and the Refresh Token process is never called.
  8. User has to log in again because the Refresh Token mechanism didn't happen.

I guess my question is: Is OnAuthenticationFailed the best way to determine if the JWT token has expired, or is there a more reliable way? I've looked online but can't find any resources to explain this.

CodePudding user response:

I think I've found an alternative way of refreshing the tokens which doesn't require the expired JWT cookie to be sent at all.

I'd followed a tutorial which used the JwtBearerEvents.OnAuthenticationFailed event to capture expiry and, as I'm a bit new to this, had to go through it all with a fine toothcomb to work out why it wasn't working.

The client-side code now responds to the simple 401 NotAuthorized status and that kicks of the process to refresh the token, which only requires the Refresh Token cookie to be sent.

CodePudding user response:

after you authoried succeeded

app.Use(async(context,next)=> 
{                
var claims = context.User?.Claims;
var exp = claims.FirstOrDefault(x => x.Type == "exp");
await next.Invoke();            
});

It would copy the claims to httpcontext,and there's a claim typed of exp indicates the seconds from 1970-1-1 to your token exp time

  • Related