0

I'm currently trying to validate a JWT in the manner that was suggested in the following answer

Here the code sample

try 
{
 tokenHandler.ValidateToken(token, validationParameters, out validatedToken);
} 
catch (Exception e) 
{
 log(e.ToString()); //something else happened
 throw;
}

Is there a better way to achieve something like this without the try/catch clause? To me it seems to be quite the messy solution, especially when hooking this function up to a controller.

Thanks!

user3024750
  • 105
  • 1
  • 11
  • notice the handling of `SecurityException` – Daniel A. White Jul 03 '19 at 18:35
  • @DanielA.White That is what I'm currently catching as well, simply left it out for simplicity in the example. Was just wondering if there's a better way to achieve this as catching all the different `SecurityException` variants (Invalid Signature, Expired ...) seems to be a non optimal solution to this problem – user3024750 Jul 03 '19 at 19:19

1 Answers1

1

The wonderful thing about Net Core is that this is built in. You actually dont need to validate the tokens yourself. If the token is invalid, a response is automatically fired back to client for you. IF however, you do feel the need to dive in and manually validate - you can do this: https://www.jerriepelser.com/blog/manually-validating-rs256-jwt-dotnet/

Ok, so i've dug out some code from the bowels of one of my projects.. Basically it lets me hook into the events that occur when a token is validated and assign my own even handlers to various points.

I believe this is what you are looking for.

Add this code to your IServiceCollection registrations:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddCustomJwtBearer(options =>
        {
            options.TokenValidationParameters = tokenParams;
            options.Events = ConfigureJwtEvents(tokenConfiguration);
        });

And this code into a STATIC class somewhere so you can call it as an extension method:

public static void AddCustomJwtBearer(this AuthenticationBuilder builder, Action<JwtBearerOptions> options)
    {
        builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, JwtBearerPostConfigureOptions>());
        builder.AddScheme<JwtBearerOptions, JwtBearerHandler>("Bearer", null, options);
    }


/// <summary>
/// Returns a configured <see cref="JwtBearerEvents"/>
/// </summary>
/// <param name="tokenConfiguration">Token Configuration</param>
/// <returns><see cref="JwtBearerEvents"/></returns>
private static JwtBearerEvents ConfigureJwtEvents(TokenConfiguration tokenConfiguration)
{
    var bearerEvents = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }

         return Task.CompletedTask;
        }
    };

    // Authentication Failed Method
    bearerEvents.OnAuthenticationFailed = [YOUR-EVENT-HANDLER]

    // Challenge Raised Event
    bearerEvents.OnChallenge = [YOUR-EVENT-HANDLER]

    // Message Received Event
    bearerEvents.OnMessageReceived = [YOUR-EVENT-HANDLER]

    // Token Validated Event
    bearerEvents.OnTokenValidated = [YOUR-EVENT-HANDLER]

    return bearerEvents;
}

Where it says: [YOUR-EVENT-HANDLER] .. You can add in your own event handler methods and they will fire if/when each of those events happens.

Robert Perry
  • 1,906
  • 1
  • 14
  • 14
  • Thanks! This is exactly what I'm doing right now though, the problem is that the `ValidateToken` method returns the `ClaimsPrincipal` when the token is valid or throws a `SecurityTokenException` if its invalid, which to me seems a bit weird as I'd have to catch the exception to come to the conclusion that the token is invalid. Any ideas how I could circumvent this? – user3024750 Jul 03 '19 at 19:13
  • @user3024750 the jwt library is open source. you could certainly extend and customize it. – Daniel A. White Jul 03 '19 at 19:35