SSE heartbeat request not authenticated with LimitToAuthenticatedUsers

If the ServerEventsFeature.LimitToAuthenticatedUsers option is enabled, the authentication check is only done when creating the subscription, but not when handling a heartbeat request.

This means that if the user logs out (or the session expires), when the heartbeat requests are sent, they will be accepted and the subscription will remain alive. I would expect the handler to return a 401 error in this case, but it doesn’t.

The ServerEventsHandler does the auth check:

if (feature.LimitToAuthenticatedUsers && !session.IsAuthenticated)
{
    session.ReturnFailedAuthentication(req);
    return TypeConstants.EmptyTask;
}

But the ServerEventsHeartbeatHandler does not.

Is this by design?

It’s by design, there’s a non-trivial cost to fetching the Users Session which is avoided per reoccurring heartbeat.

It’s not really alive. If the Users logs out/leaves then their long-running SSE HTTP subscription is terminated, keeping it alive with heartbeats only keeps its registration alive, but any message that’s sent to the subscription goes into the void. The SSE registration is also forcibly unregistered when the User calls the unregisteredUrl on window.unload or SSE client.Stop() in native SSE clients or there’s an Exception when publishing a message to a non-existent SSE subscription.

The subscriptionId that’s sent on the heartbeat has the same entropy as a Users Session Id and it’s private to each User, i.e. there’s no way to find out other Users subscription Id and you have the same chance at guessing someone elses random SSE subscription Id as you would a Users Session Id.