HardLuck
HardLuck

Reputation: 1577

ServiceStack ServerSentEvents restrict access to channel

In my ServiceStack app I would like to deny access to channels for unauthorized users - so even the join event would not fire for an unauthorized client. I am using custom auth provider that does not interact with the DB and is very minimalistic for now (mainly for testing purposes)

public class RoomsAuthProvider : CredentialsAuthProvider
{
    private int userId = 0;

    public RoomsAuthProvider(AppSettings appSettings) : base(appSettings)
    {
    }

    public RoomsAuthProvider()
    {
    }

    public override bool TryAuthenticate(IServiceBase authService,
        string userName, string password)
    {
        if (password == "ValidPassword")
        {
            return true;
        }

        else
        {
            return false;
        }
    }

    public override IHttpResult OnAuthenticated(IServiceBase authService,
        IAuthSession session, IAuthTokens tokens,
        Dictionary<string, string> authInfo)
    {
        //Fill IAuthSession with data you want to retrieve in the app eg:
        session.FirstName = "some_firstname_from_db";
        //...

        //Call base method to Save Session and fire Auth/Session callbacks:
        return base.OnAuthenticated(authService, session, tokens, authInfo);

        //session.CreatedAt = DateTime.Now;
        //session.DisplayName = "CustomDisplayName" + userId;
        //session.IsAuthenticated = true;
        //session.UserAuthName = session.UserName;
        //session.UserAuthId = userId.ToString();

        //Interlocked.Increment(ref userId);

        //authService.SaveSession(session, SessionExpiry);
        //return null;
    }
}

Main service piece:

[Authenticate]
public class ServerEventsService : Service
{
...
}

sidenote - I have tried overriding the default DisplayUsername to not be username1...usernameN but no luck. My client code is

var client = new ServerEventsClient("http://localhost:1337/", "home")
{
    OnConnect = OnConnect,
    OnCommand = HandleIncomingCommand,
    OnMessage = HandleIncomingMessage,
    OnException = OnException,
    OnHeartbeat = OnHeartbeat
}.Start();

client.Connect().Wait();

var authResponse = client.Authenticate(new Authenticate
{
    provider = "credentials",
    UserName = "[email protected]",
    Password = "p@55w0rd",
    RememberMe = true,
});

client.ServiceClient.Post(new PostChatToChannel
{
    Channel = "home",     // The channel we're listening on
    From = client.SubscriptionId, // Populated after Connect() 
    Message = "Hello, World!",
});

Even if I skip the authenticate call the other clients will still get onJoin command about not authenticated client when it tries to do an unauthorized post (and get an error). Also when I intentionally do multiple unauthorized users counter grows - assigned username becomes username2, username3 and so on - how can I disable unauthorized users COMPLETELY? Marking my DTOs with Authenticate also didn't change anything. Any ideas are welcome as well as crytics as I'm new to ServiceStack and would like to implement the best practices.

Upvotes: 1

Views: 80

Answers (1)

mythz
mythz

Reputation: 143319

There's already an option to limit access to authenticated users only with:

Plugins.Add(new ServerEventsFeature {
    LimitToAuthenticatedUsers = true
});

Upvotes: 2

Related Questions