AuthKey required to use: HS256

We are trying to manually build some JWT tokens for various purposes according to the documentation at https://docs.servicestack.net/jwt-authprovider#creating-jwt-tokens-manually

But we keep getting this error: AuthKey required to use: HS256

Here is our Plugin setup:

new AuthFeature(() => new CustomAuthUserSession(), new IAuthProvider[]
                {
                    new CustomAuthProvider()
                    {
                        PersistSession = true,
                    },
                    new CustomJwtAuthProvider()
                    {
                        AuthKeyBase64 = host.AppSettings.Get<string>("AuthKeyBase64"),
                        HashAlgorithm = "HS256"
                        RequireSecureConnection = false,
                    },
                })

Here is our GenerateJwt method:

public string GenerateJwt(int userId)
        {
            var header = JwtAuthProvider.CreateJwtHeader(provider.HashAlgorithm);
            var body = JwtAuthProvider.CreateJwtPayload(new CustomAuthUserSession()
                {
                    UserAuthId = userId.ToString(),
                    FirstName = user.FirstName,
                    LastName = user.LastName,
                    FullName = user.FullName,
                    DisplayName = user.FullName,
                    Email = user.Email,
                    AgencyId = user.AgencyId,
                    StateAbbreviation = StateEnum.FromValue(agency.PrimaryStateId.Value).Abbreviation,
                    StateId = agency.PrimaryStateId.Value,
                    TimeZone = agency.Timezone
                },
                issuer: provider.Issuer,
                expireIn: provider.ExpireTokensIn,
                audiences: new[] {provider.Audience},
                roles: roles,
                permissions: perms);

            var jwtToken = JwtAuthProvider.CreateJwt(header, body, provider.GetHashAlgorithm());

            return jwtToken;
        }

Am I misunderstanding where or how to set the AuthKey?

This line throws the error:

JwtAuthProvider.CreateJwt(header, body, provider.GetHashAlgorithm());

How are you getting the provider? from AuthenticateService.GetRequiredJwtAuthProvider()?

Otherwise if you’re creating a new JwtAuthProvider you’ll need to populate it with the same config.

Sorry I left that part out, here is the full method:

public string GenerateJwt(int userId)
        {
            var provider = ResolveService<CustomJwtAuthProvider>();
            var repo = AuthRepository as CustomAuthRepository;
            var perms = repo.GetPermissions(userId.ToString());
            var roles = repo.GetRoles(userId.ToString());
            var user = Db.SingleById<User>(userId);
            var agency = Db.SingleById<Agency>(user.AgencyId);

            var header = JwtAuthProvider.CreateJwtHeader(provider.HashAlgorithm);
            var body = JwtAuthProvider.CreateJwtPayload(new CustomAuthUserSession()
                {
                    UserAuthId = userId.ToString(),
                    FirstName = user.FirstName,
                    LastName = user.LastName,
                    FullName = user.FullName,
                    DisplayName = user.FullName,
                    Email = user.Email,
                    AgencyId = user.AgencyId,
                    StateAbbreviation = StateEnum.FromValue(agency.PrimaryStateId.Value).Abbreviation,
                    StateId = agency.PrimaryStateId.Value,
                    TimeZone = agency.Timezone
                },
                issuer: provider.Issuer,
                expireIn: provider.ExpireTokensIn,
                audiences: new[] {provider.Audience},
                roles: roles,
                permissions: perms);

            var jwtToken = JwtAuthProvider.CreateJwt(header, body, provider.GetHashAlgorithm());

            return jwtToken;
        }

Firstly ResolveService<T> is only for resolving ServiceStack Services, you can use TryResolve<T> for resolving dependencies registered in the IOC.

But the AuthProvider is not an IOC dependency, you can resolve your Auth Providers you’ve registered in your AuthFeature with:

var provider = AuthenticateService.GetRequiredJwtAuthProvider();
var provider = AuthenticateService.GetAuthProvider(JwtAuthProviderReader.Name);

Or if you’ve changed the name of your provider you can resolve it by type:

var provider = AuthenticateService.GetAuthProviders().First(x => x is CustomJwtAuthProvider) as (CustomJwtAuthProvider);

D’oh, I always get those mixed up, thank you. That got rid of the error.

One last question regarding manual JWT token creation / usage:

Does this affect how PopulateSessionFilter works on the JwtAuthProvider?

When I login normally with creds, then use the bearerToken given back, the PopulateSessionFilter works as expected (and the payload has 15 keys - the 11 base keys + my 4 custom keys). All is well.

But when I generate a token manually, switch my client to start using that bearerToken, PopulateSessionFilter’s payload arg only has the 11 base keys, so this fails:

PopulateSessionFilter = (session, payload, req) =>
                {
                    var s = session as CustomAuthUserSession;
                    s.AgencyId = int.Parse(payload["AgencyId"]); // DOESNT EXIST
                    s.StateAbbreviation = payload["StateAbbreviation"]; // DOESNT EXIST
                    s.StateId = int.Parse(payload["StateId"]); // DOESNT EXIST
                },

Is there some other mechanism I’m missing?

FYI you can use https://jwt.io to inspect the contents of your JWT.

If you’re using the static methods the PopulateSessionFilter instance filters can’t be used, there are provider.CreateJwtBearerToken() instance methods you can use to create JWT’s using the configured instance properties, otherwise you should be able to reuse the filter with something like:

var body = JwtAuthProvider.CreateJwtPayload(session);
provider.CreatePayloadFilter(body,session);