-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Describe the bug
The JWT silent renew in the React template with authentication can fail in some scenarios. What happens is the token is listed as expired (user.expires_in is negative and outside the 5 minute clock skew grace period). As a result, the API request fails with a 401, the token is never renewed, and the user can no longer get into [Authorize] marked areas. The only way to solve this I found (and the workaround isn't even confirmed), is to explicitly press the logout button and restart my application (presumably to reset authentication/authorization on the client side SPA).
If you don't explicitly log out, this issue will persist even on restarts of the ASP.NET application presumably because it's a client side issue. There are a lot of steps to the below so some may or may not actually contribute to the issue but it is a consistent repro.
To Reproduce
- Create a new React based ASP.NET application with Individual User authentication
- Reduce the AccessTokenLifetime parameter by modifying the call .AddApiAuthorization to:
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(opt =>
{
foreach (var c in opt.Clients)
c.AccessTokenLifetime = 65;
});
- The default is an hour but that's way too long to repro.
- Start the application, register a new account and let it auto-login for you
- Now explicitly log out
- Then login again with your newly created account and make sure to tick the Remember Me box.
- Now stop the application.
- Wait for at least 65 seconds (ie. wait until the JWT access token expires).
- Start the application again with debugging on (if you want to be able to see the expired token live forever; see the last image in this report)
- Wait for 5 minutes while the clock skew grace period is consumed.
- Try to access the Fetch Data page which requires authentication/authorization.
Expected outcome: You get to the Fetch Data page with a renewed JWT.
Actual outcome: A crash with a JWT that hasn't and apparently won't renew.
You can break into AuthorizeService.js and inspect the user value to see that the token is expired. You can actually see the token work and count more and more negative until it gets to 300 at which point it'll then fail.:
Further technical details
- ASP.NET Core 3
- VSCode
.NET Core SDK (reflecting any global.json):
Version: 3.0.100
Commit: 04339c3a26
Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.0.100\
Host (useful for support):
Version: 3.0.0
Commit: 7d57652f33
.NET Core SDKs installed:
3.0.100 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download

