CustomUserSession & JWTAuthProvider in

Hi, We would like to use tokens. We have a CustomUserSession

Public Class CustomUserSession
    Inherits AuthUserSession
    Public Property CurrentUser As V_Users
    Public Property CurrentContact As V_Contacts
    Public Property SecureOperations As List(Of Secure_Operations)
    Public Property test As String
End Class

Configure has:

appHost.Plugins.Add(New AuthFeature(Function() New CustomUserSession(), {
    New JwtAuthProvider(appSettings) With {
    .AuthKeyBase64 = "Ai7UHpjLLJTLQ7Iskp8WpQGyGM4I7VbPWexLvtUC3C0=",
    .UseTokenCookie = True,
    .SetBearerTokenOnAuthenticateResponse = True,
    .RequireSecureConnection = False,
    .CreatePayloadFilter = Function(payload, session) payload("test") = "t",
    .PopulateSessionFilter = Function(session, payload, request) 
CType(session, CustomUserSession).test = "t" 
 }, New CustomCredentialsAuthProvider()}) With {.IncludeAssignRoleServices = False}) 

OnAuthenticated has:

authService.GetSessionBag().Set(Of V_Users)("CurrentUser", CurrentUser)
authService.SaveSessionAsync(session, SessionExpiry)
Return MyBase.OnAuthenticated(authService,session, tokens, authInfo)

My understanding was that:

  1. CurrentUser would be retrieved on the next request by JWTAuthProvider as CurrentUser is saved as part of the session
  2. payload would contain test yet when I decode the jwt via, the payload does not show test; only the defaults.
  3. session.test on the next request would be populated due to the .PopulateSessionFilter
    is that correct?

I did try adding variations of

authService.Request.Items("CurrentUser") = CurrentUser
Dim CustomUserSession As CustomUserSession = session
CustomUserSession.CurrentUser = CurrentUser
Return MyBase.OnAuthenticated(authService, CustomUserSession, tokens, authInfo)

The second request gets to:

Partial Public Class MAutoQueryServiceBase
Inherits AutoQueryServiceBase
	Public Overrides Function ExecAsync(Of From)(dto As IQueryDb(Of From)) As Task(Of Object) 
		Dim session = SessionAs(Of CustomUserSession)()

at which point I was expecting the session to have the values from before (I left only the ss-tok cookie in the Postman request) but both CurrentUser and test are Nothing.

I tried to follow the well laid out example at

and still seem to be missing something and not sure if that is due to my C# -> translation or incomplete understanding. Thanks for any pointers!

  1. CurrentUser would be retrieved on the next request by JWTAuthProvider as CurrentUser is saved as part of the session

JWTs are a stateless replacement for Server Sessions, i.e. clients using JWT Auth should not be using Server Sessions as well.

JWT Tokens by design only contain minimal auth info in their payloads, any additional info you want to keep in JWTs need to be added in CreatePayloadFilter to add the info to the JWT that’s subsequently accessed in PopulateSessionFilter to populate the authenticated User Session for that request.

The alternative to embedding session state in the JWT is to have services that need them to fetch from the DB by the authenticated User Id.

Yes that’s correct, since your CreatePayloadFilter is populating payload["test"] it should be embedded in the JWT Body payload. It’s not clear why it’s not, I’d assume the JWT you’re inspecting isn’t the one that’s populated. If you can put together a small stand-alone repro on GitHub I can run locally, I can tell you what the issue is.

You’re going to need a completely different strategy as mentioned above (i.e. embed in JWT or fetch from DB) if using JWTs as any custom Session Info isn’t going to be embedded in the JWT Auth Session and clients that use JWT should not be using Server Sessions.

Forum Posting Tips:

So your future posts are readable can you please markup any source code with markdown code blocks, e.g:

// VB Code

// C# Code

Please also scrub any sensitive info posted in the forums, e.g.

.AuthKeyBase64 = "...", //instead of
.AuthKeyBase64 = "Ai7UHpjLLJTLQ7Iskp8WpQGyGM4I7VbPWexLvtUC3C0=",

Consider this key compromised if it’s used anywhere in production.

Thanks, I pared it down, put it on github and invited you to it. Hopefully did it ok.

Ooh, I added another property to the payload and now both show up when I decode the payload so maybe it was my lack of C# -> vb. I will see what I can do with those.

I’m not sure what you mean by Server Session. Does that mean anything referencing authService should not be used?

Thanks for your time!

I’ve debugged your payload issue which for some reason the payload wasn’t getting modified, which I’ve tracked down that in VB .NET you need to use Sub for .NET Action's and Function for .NET Func's.

.CreatePayloadFilter = Sub(payload, session) payload("test") = "t",

Also I’ve noticed you’re using string concatenation for creating SQL which you should never do with user defined input, you should instead use parameters instead with Custom SQL instead, which in VB.NET should look something like:

db.Select(Of V_Users)("select * from V_Users where loginname=@user", New With {.user = userName})