Stale signing key cache results in 401 response during key rollover in JwtBearerHandler
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is your feature request related to a problem? Please describe.
Following a signing key rollover, it appears that `Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler` may incorrectly report an authentication failure (which results in a 401 Unauthorized response) in `HandleAuthenticateAsync` due to a stale local cache of the signing keys.
`Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler` relies on `Microsoft.IdentityModel.Protocols.IConfigurationManager` as a cache for the signing keys when validating the signature in JWT tokens. In `HandleAuthenticateAsync()`, when authentication fails due to `SecurityTokenSignatureKeyNotFoundException` (which may legitimately occur due to key rollovers), `JwtBearerHandler` simply calls `IConfigurationManager.RequestRefresh()`, which does not refresh the signing keys immediately. Instead, it sets a timestamp which causes the configuration to be refreshed beginning with the next request. The request in question will still fail at the authentication stage. The relevant code here:
https://github.com/dotnet/aspnetcore/blob/41eab27ef39706c5c08183c740eb0d5f3ab32df4/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs#L124-L128
### Describe the solution you'd like
From my point of view, upon encountering a `SecurityTokenSignatureKeyNotFoundException`, the signing keys should be refreshed immediately and signature validation should be attempted again with the refreshed keys, all within that same request lifetime. However, I suspect that the reason that this is not done is deliberate - as mentioned in https://github.com/dotnet/aspnetcore/issues/26504#issuecomment-702364883:
> This is about a request using a consistent configuration for all stages. We wouldn't want the config to change part way through or you could get inconsistent results.
But this actually results in incorrect 401 responses - the user should in fact be authenticated, and the system fails to authenticate the user purely due to some technical constraints that causes the authentication to be based on stale data. In a distributed system, this may result in a spike in 401 responses across the system when key rollover occurs - certainly a less than ideal situation.
Contributor guide
Assessment
This issue has not been assessed yet.