Question about SSE

Can we do in ServiceStack with SSE the following use case?

  1. User is authenticated already (or first time), he asks from a REST Point to be subscribed in SSE channels.
  2. The service returns a URL path of a subdomain (maybe to be the same domain, but also it could be other ServiceStack running in subdomain).
    It returns also a path to channels, specific to user (or team of users), different each time according to circumstances. It returns also a subscription token for these channels.
  3. User would be subscribed in the SSE channels, using (except his cookie) the token for SSE.
  4. Time to time the SSE server, will ask from the user to revalidate his token.
  5. User calls again the initial REST point and in his request, he includes the old taken, the service informs the SSE server and creates a new subscription token.
  6. In case that the connection was lost. the client call again the service and if he has the previous token (not expired) maybe to be possible to get some messages, that he should not miss.
    Can I do this use case with the ServiceStack ?
    EDIT: I mean if there are any problems as I will proceed with such implementation.
    thanks.

Yes, making an authenticated request to the SSE Event Stream will connect as an authenticated user.

  1. The service returns a URL path of a subdomain (maybe to be the same domain, but also it could be other ServiceStack running in subdomain).
    It returns also a path to channels, specific to user (or team of users), different each time according to circumstances. It returns also a subscription token for these channels.

I’m assuming you’re referring to your own Custom Service so you can return whatever you like. There’s no concept of “subscription token for channels” so that’s something you’d need to implement yourself and validate in an SSE OnCreated filter.

  1. User would be subscribed in the SSE channels, using (except his cookie) the token for SSE.

If you’re not referring to a JWT Token from ServiceStack’s built-in JWT AuthProvider you would need to create a Custom AuthProvider, likely similar to how JWT AuthProvider is implemented.

  1. Time to time the SSE server, will ask from the user to revalidate his token.

That would be up to your Custom Logic to implement to send a notification to subscribed clients that they’d act on. If you’re using JWT Refresh Tokens the clients would automatically fetch new JWT Tokens when they’ve expired.

  1. User calls again the initial REST point and in his request, he includes the old taken, the service informs the SSE server and creates a new subscription token.

If you’re not referring to the recent JWT Refresh Tokens support added in the last release, that’s something else you’d have to implement.

  1. In case that the connection was lost. the client call again the service and if he has the previous token (not expired) maybe to be possible to get some messages, that he should not miss.

All SSE Clients have built-in auto-reconnect + heartbeats, but this reference to token concept is unclear of how you want it to work whether you want to take advantage of built-in functionality or building your own alternative app-level solution on top.

Approach using built-in ServiceStack features

All these series of instructions are a bit vague, you’ve not disclosed which SSE Client you’d like to implement this for or have really stated a use-case here just a series of specific implementation steps of how you want it to work.

My preference is instead start with the solution I need and work backwards to find out what built-in ServiceStack features I can utilize to implement it and if there’s ever something missing I’d just extend ServiceStack or make a custom filter available in order to provide the necessary hooks I need (we’re open to include any PRs/Hooks that others would need as well). I believe you can get close using the built-in JWT AuthProvider, you’d likely need to create a custom JWT Payload either using a custom CreatePayloadFilter so when the User Authenticates you can embed which channels they have access to, then you’d implement PopulateSessionFilter to unpack the JWT Token and populate your Custom UserSession or you could instead use the JwtAuthProvider.CreateJwtHeader(), .CreateJwtPayload() and .CreateJwt() static methods directly to generate a custom JWT Payload in a Custom Service, or if you prefer to use your own Token implementation, in which case you’d need to unpack it yourself, likely in a Request Filter.

I’d authenticate using the SSE Service Client using a JWT Token Cookie so it’s sent with every request.

When they make an SSE Connection you can use a Server Events Custom Event Hook to validate the request by accessing the Custom UserSession populated automatically from the JWT Token or you can use the ConvertJwtToSession() instance method to populate a user session from a JWT Token or GetVerifiedJwtPayload() to extract the JWT Payload body that you can inspect.

For the re-validation I’d look at trying to take advantage of Refresh Tokens support which is built in to the C# and TypeScript Service Clients to automatically fetch new JWT Tokens using a RefreshToken when they expire and resubmit auth-failed requests behind the scenes.

So it really depends on how much of the built-in features you’re able to use, you could go your own way and implement a Custom Auth Provider or Custom Auth/Session Events, use your own app-level Custom Token implementation and depending on how fine-grained behavior you want with the SSE client you maybe able to use the built-in event handlers or maybe you need a modified SSE client instead.

Framing better questions

These types of questions are really open ended, I can’t really tell from this high-level description if ServiceStack has all the built-in features to make it easy to implement your use-case or if you need it to work a specific way in which case you’re going to need to implement a lot of the features yourself. It’d be preferential if you asked more specific questions on how to accomplish specific tasks that way the answer provided would be clearer and more definitive.

1 Like

I appreciate your directions,
Yes, I talked about custom logic . Of course the information about the JWT Token (and Refresh Tokens) is very useful. Also I will use JavaScript and C# SS Clients.
What I was asking essentially, is that in my use case,
the client does not know, from before, in which server(subdomain) will be subscribed for SSE. in which event channels and also only some users/clients
will get validated to participate in these or other channels , and with roles for each one.
All such information will be provided from the REST Service, in which the client will request his subscription. He will be authenticated before in order to call the service (with the service’s cookie). The validation token (custom logic) will be his “passport” to participate in different available channels (beyond the JWT service authentication token).
I was asking if I will meet problems with this implementation, using the ServiceStack’s infrastructure.

I don’t forsee an issue, clients can connect to any url and specify which channels they want to be subscribed to when connecting. If using TypeScript/JS you’ll need to enable CORS to enable cross-domain access. JWT enables stateless auth services which is what I’d use to implement the “passport”, my previous answer listed different ways to go about creating/processing the JWT Token.

1 Like