简体   繁体   中英

ServiceStack GetSession during heartbeat

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM