Security token events return a JsonWebToken

The JwtBearerEvents, WsFederationEvents, and OpenIdConnectEvents events are authentication events fired respectively by the JwtBearer, WsFederation, and OpenIdConnect authentication handlers. For example, the OnTokenValidated event is fired when a security token is validated. These events are fired with a context (for example, TokenValidatedContext) that exposes a TokenValidatedContext.SecurityToken property of abstract type SecurityToken. The default real implementation of TokenValidatedContext.SecurityToken changed from JwtSecurityToken to JsonWebToken.

Version introduced

ASP.NET Core 8.0 Preview 7

Previous behavior

Previously, the affected SecurityToken properties were implemented by JwtSecurityToken, which derives from SecurityToken. JwtSecurityToken is the previous generation of JSON Web Token (JWT) implementation. The JwtSecurityToken tokens were produced by SecurityTokenValidators.

In addition, the JwtSecurityTokenHandler.DefaultInboundClaimTypeMap field provided the default claim type mapping for inbound claims.

New behavior

Starting in ASP.NET Core 8.0, the Microsoft.IdentityModel.JsonWebTokens class, which also derives from SecurityToken, implements the SecurityToken properties, by default. Microsoft.IdentityModel.JsonWebTokens tokens are produced by more optimized TokenHandler handlers.

In addition, the JsonWebTokenHandler.DefaultInboundClaimTypeMap field provides the default claim type mapping for inbound claims.

Type of breaking change

This change is a behavioral change.

Reason for change

This change was made because JsonWebToken (and its associated JsonWebTokenHandler) bring the following benefits:

  • 30% performance improvement.
  • Improved reliability by using a "last known good" metadata (such as OpenIdConnectMetadata).
  • Async processing.

For most users, this change shouldn't be a problem as the type of the properties (SecurityToken) hasn't changed, and you weren't supposed to look at the real type.

However, if you were down-casting one of the affected SecurityToken properties to JwtSecurityToken (for example, to get the claims), you have two options:

  • Down-cast the property to JsonWebToken:

    service.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options => {
        options.Events.OnTokenValidated = (context) => {
            // Replace your cast to JwtSecurityToken.
            JsonWebToken token = context.SecurityToken as JsonWebToken;
            // Do something ...
        };
    });
    
  • Set one of the UseSecurityTokenValidators Boolean properties on the corresponding options (JwtBearerOptions, WsFederationOptions, or OpenIdConnectOptions) to true. By setting the property to true, the authentication handlers will keep using JwtTokenValidators and will keep producing JwtSecurityToken tokens.

    service.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme,  options => {
        options.UseSecurityTokenValidators = true;
        options.Events.OnTokenValidated = (context) => {
            // As you were doing before
            JwtSecurityToken token = context.SecurityToken as JwtSecurityToken;
            // Do something ...
        };
    });
    

Affected APIs