I have a servicestack app in which I would like to make some session-related updates during heartbeat.
My simplified host code:
internal class SelfHost : AppSelfHostBase
{
public SelfHost() : base("HttpListener Self-Host", typeof(ServerEventsService).Assembly)
{
}
public override void Configure(Container container)
{
Plugins.Add(new ServerEventsFeature
{
LimitToAuthenticatedUsers = true,
NotifyChannelOfSubscriptions = false,
OnHeartbeatInit = req =>
{
var userSession = req.GetSession();
var sessionKey = SessionFeature.GetSessionKey(req.GetSessionId());
}
});
container.Register<ICacheClient>(new MemoryCacheClient());
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[]
{
new CredentialsAuthProvider
{
SessionExpiry = TimeSpan.FromSeconds(30),
SkipPasswordVerificationForInProcessRequests = true,
},
})
);
var userRep = new InMemoryAuthRepository();
container.Register<IUserAuthRepository>(userRep);
string hash;
string salt;
var pwd = "ValidPassword";
new SaltedHash().GetHashAndSaltString(pwd, out hash, out salt);
userRep.CreateUserAuth(new UserAuth
{
Id = 3,
DisplayName = "CustomDisplayName2",
Email = "test2@gmail.com",
UserName = "CustomUserName2",
FirstName = "FirstName2",
LastName = "LastName2",
PasswordHash = hash,
Salt = salt,
}, pwd);
}
}
and the simplified client code:
var mainClient = new ServerEventsClient(baseUrl, "home");
var authResponse = mainClient.Authenticate(new Authenticate
{
provider = "credentials",
UserName = "CustomUserName2",
Password = "ValidPassword",
RememberMe = false,
});
mainClient.Connect().Wait();
It connects and authenticates fine, the problematic part start in OnHeartbeatInit
- my session here is always a new non authenticated session that has only Id, CreatedAt and LastModified. My service is marked with [Authenticate]
attribute on class level. Have I misconfigured or lost some config that should allow that? If I post to my service and call Request.GetSession()
then I get a populated session which I expect to see in OnHeartbeatInit
as well.
Sidenote: there are no hidden configs anywhere, I have created a separate app exclusively for this example.
The issue is that the heartbeats requests sent in .NET ServerEventsClient
isn't sent with the same CookieContainer
that the client authenticates or connects to the /event-stream
with, which is what contains the Session Cookies.
I've updated the ServerEventsClient
so heartbeat requests now reference the same CookieContainer for every heartbeat request in this commit.
This change is available from v4.0.55 that's now available on MyGet.