I’m having lots of problems with my custom authentication providers, and I think it’s due to my lack of understanding of how they work. Our app is a React application, with a ServiceStack backend.
In my CustomCredentialsAuthProvider, we load additional data into our CustomAuthUserSession. It’s there in the db. I see it in the CacheEntry table in the database. When calling services that use SessionAs() - sometimes the data is populated and sometimes it’s not. Sometimes the provider on CustomAuthUserSession says credentials, sometimes it says jwt. Right now I can look in the database and see a CacheEntry with my roles, permissions, and two custom fields (agencyId and stateAbbreviation), with a provider of credentials.
Yet when I hit my endpoint and call SessionAs(), it says my provider is jwt. It has the roles, permissions, firstName, lastName populated - but not the agencyId or stateAbbreviation. I’ve resorted to using GetSession(true) which works sometimes, but not always. What gives? Am I just misunderstanding how the bearerToken / refreshToken should be used?
Here is our auth process:
User enters email / password, we call this code to POST the new Authenticate() TS DTO:
const request = new Authenticate();
request.provider = 'credentials';
request.userName = email;
request.password = password;
const data = await client.post(request);
setToken(data.bearerToken, data.refreshToken); // this sets the token on our client for all future calls
return data;
You see that we set the token afterwards for all future calls.
Here is my OnAuthenticated method of CustomCredentialsAuthProvider:
public override IHttpResult OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
var dbFactory = authService.ResolveService<IDbConnectionFactory>();
using (var db = dbFactory.Open())
{
var user = db.LoadSelect<User>(x => x.Email.ToLower() == session.UserAuthName.ToLower()).FirstOrDefault();
var state = StateEnum.FromValue(user.Agency.PrimaryStateId.Value);
var roles = LoadPermissionGroups(db, user) ?? new List<string>();
var permissions = LoadPermissions(db, user) ?? new List<string>();
session.UserAuthId = user.Id.ToString();
session.FirstName = user.FirstName;
session.LastName = user.LastName;
session.DisplayName = user.FirstName + " " + user.LastName;
session.Email = user.Email;
session.UserName = user.Email;
session.Roles = roles;
session.Permissions = permissions;
(session as CustomAuthUserSession).AgencyId = user.AgencyId;
(session as CustomAuthUserSession).StateAbbreviation = state.Abbreviation;
}
return base.OnAuthenticated(authService, session, tokens, authInfo);
}
All of this is duplicated in a CustomBasicAuthProvider and CustomJwtAuthProvider. The BasicAuthProvider is currently only used for swagger and will be removed. I added CustomJwtAuthProvider in an attempt to get these values to populate to no avail.
Is there some conversion between credentials and jwt that I’m missing? Why do I intermittently get values for stateAbbreviation and agencyId?