Decoding JWT in another webapp

I have an ASP MVC web application running over the top of an array of Micro Services (Service Stack Services).

The web application authenticates against one of the micro-services and receives a JWT.

I am wanting to decode the JWT within the web application, so that I can apply local authorization without having to go to the API to get rejected (also to control visibility of features within the app).

I have tried the following

  • I have descended my controller classes from ServiceStackController
  • Authenticate against the micro
var authClient = new JsonServiceClient(ConfigurationManager.AppSettings["Service.Account.URL"]);
var authResponse = authClient.Get(new Authenticate
{
    provider = "credentials",
    UserName = user,
    Password = pass,
    RememberMe = true,
});

if (authResponse != null)
{
    HttpContext.Current.Session[BearerToken] = authResponse.BearerToken;
    return true;
}
  • Attempted to retrieve the session using
var session = base.SessionAs<AuthUserSession>();

however the session is always empty.

I suspect after the authentication, I need to do something additional with the jwt that I receive in order for the SessionAs to work as intended. I also have no reference to the encoding key, so I must need to do something there also

Any help would be appreciated.

Also, is it possible to decode this jwt without having to invoke the apphost engine and descend controllers ?

I hooked up the auth provider on the apphost in the web app as per below, but this did not resolve the problem

    Plugins.Add(new AuthFeature(() => new CustomSession(),
        new IAuthProvider[]
        {
            new JwtAuthProvider(AppSettings)
            {
                AuthKey = System.Convert.FromBase64String("XXXX..........."),
                RequireSecureConnection = false,
                CreatePayloadFilter = (payload, session) =>
                {
                    payload["AccountID"] = (session as CustomSession).AccountID;
                    payload["exp"] = DateHelper.UnixTimeNow(1).ToString();
                },
                PopulateSessionFilter = (session, payload, req) =>
                    (session as CustomSession).AccountID = payload["AccountID"]
            }
        }));

The Microservices that also wants to validate the JWT Token should have the same AuthKey registered that was used to issue the tokens, but as it’s not issuing tokens it can just register a JwtAuthProviderReader, e.g:

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new IAuthProvider[] {
        new JwtAuthProviderReader(AppSettings) {
            AuthKey = ...
        },
    }));

To validate JWT Tokens manually have a look at the Adhoc JWT APIs, you can access the decoded JWT body with:

var jwtProvider = AuthenticateService.GetJwtAuthProvider();
JsonObject payload = jwtProvider.GetValidJwtPayload(authResponse.BearerToken);
var userId = payload["sub"];

The session API is for returning the Session on the incoming request, so if the user isn’t authenticated SessionAs<T> will return an empty session.

Instead you can extract the UserSession from the JWT with:

var jwtProvider = AuthenticateService.GetJwtAuthProvider();
var userSession = jwtProvider.ConvertJwtToSession(base.Request, authResponse.BearerToken);

Inside a ServiceStackController you would use base.ServiceStackRequest.

I’m not sure the purpose of saving the JWT in the ASP.NET Session is though?

HttpContext.Current.Session[BearerToken] = authResponse.BearerToken;

Note: ServiceStack Sessions have nothing to do with ASP.NET Sessions which are completely unrelated. IMO you should be returning the JWT as a ss-tok Response Cookie that way the client sends it with each subsequent request to that server.

If the client sends the JWT in the ss-tok header you’ll be able to access it from your ServiceStackController with:

string jwt = ServiceStackRequest.GetJwtToken();
1 Like

Awesome information as always, I will look into these options and report back

I have this working now thanks, I rerouted the token to the ss-tok and the rest took care of itself.

1 Like