JWT breaks AuthResponseDecorator

I was just debugging why my custom AuthResponseDecorator implementation wasn’t working and I saw that it stopped working when the JWT auth provider was added to the list on the AuthFeature.

After digging into the code, I noticed that the JwtAuthProviderReader class overwrites it in the Register method.
This line is used in the AuthFeature class here. So I fixed my code to use a custom JwtAuthProvider implementation that inherits from JwtAuthProvider, and explicity added the IAuthPlugin interface to it, and added the following code, with my custom AuthenticateResponseDecoratorOverride method:

    public **new** void Register(IAppHost appHost, AuthFeature feature)
    {
        base.Register(appHost, feature);
        feature.AuthResponseDecorator = AuthenticateResponseDecoratorOverride;
    }

Weirdly, I also found that the following DOESN’T work (probably because the “Register” method isn’t virtual):

public class UserJwtAuthProvider: JwtAuthProvider

Whereas, the following DOES work:

public class UserJwtAuthProvider: JwtAuthProvider, IAuthPlugin

Not sure how you’d like to fix this (just make Register virtual?), or make this easier to work with, but I’d think it would be nice if the JWT didn’t break the “authFeature.AuthResponseDecorator” property override which is the best way I think to override the AuthenticateResponse object.

Let me know your thoughts.

It’s not breaking it, the JWT AuthProvider is the only class built into ServiceStack that uses it, and is effectively the reason for it’s existence. There shouldn’t be more than a single decorator which replaces the AuthResponse returned on successful authentication.

You can mutate the AuthenticateResponse by having your AuthProvider implement IAuthResponseFilter:

public interface IAuthResponseFilter
{
    void Execute(AuthFilterContext authContext);
}

Which gets called before AuthResponseDecorator.

I don’t want to mutate the auth response object, I want to change the type altogether as documented here :+1: , which works fine, until I add the JwtAuthProvider. The filter approach allows you to mess with the .Meta.* dictionary, but forces the client to have to use JSON.parse on meta.* properties. If the intention is for the JwtAuthProvider to hijack the decorator away from developers, I guess that should be documented somewhere. If the new type of object inherits from AuthenticateResponse or implements some similar interface, seems to me this could be made to work nicely without ceremony for any provider.

Since I have a workaround that I documented, I won’t push this. I guess maybe I don’t understand why the JwtAuthProvider has to hijack this otherwise very powerful (and documented) capability. :sob: (overly dramatic)

1 Like