Click here to Skip to main content
15,889,335 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a small project which contains a windows forms signalr client and a windows forms server. Clients can connect to server. Now, I want to implement a login system. I red some blogposts, articles and questions about this, but I didn't found a way to do it. I would like to use the signalr authentication system so I can use attributes such as [Authorize] because it's already there.

To use this, I need to validate the username and password. Can the client sends the credentials in header like this
C#
Connection = new HubConnection(BaseEngine.ServerURI);
Connection.Headers.Add("Username", username);
Connection.Headers.Add("Password", password);
HubProxy = Connection.CreateHubProxy("ChatHub");
await Connection.Start();

and the server should validate those credentials somehow in a method and throw an exception if are not valid?

Thank you!

Workaround

I have found something like a workaround: first of all, I implemented an attribute, derived from AuthorizeAttribute used by SignalR. This implementation overrides the AuthorizeHubMethodInvocation method witch is called when a method that is decorated with this attribute is called. So, in this method, I'm checking that an Authorization Token is present in the header of the request and validate the information. The client has to add this header to connect to the server. It's the easiest method I have found so far, but it's still an workaround.

Implementation, server:
C#
[AttributeUsage(AttributeTargets.Method)]
internal class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public override bool AuthorizeHubMethodInvocation(Microsoft.AspNet.SignalR.Hubs.IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
    {
        string token = hubIncomingInvokerContext.Hub.Context.Headers["AuthenticationToken"];

        if (string.IsNullOrEmpty(token))
            return false;
        else
        {
            string decryptedValue = Encryptor.Decrypt(token, Encryptor.Password);

            string[] values = decryptedValue.Split(';');

            bool b = ...check if it's ok...

            return b;
        }
    }
}


Implementation, client:
C#
ComEngine.Connection = new HubConnection(BaseEngine.ServerURI);

ComEngine.Connection.Headers.Add("AuthenticationToken", Encryptor.Encrypt(string.Format("{0};{1};{2}", BaseEngine.UserName, BaseEngine.DeviceId, BaseEngine.Password), Encryptor.Password));

try
{
    await Connection.Start();
}
catch (Exception ex)
{
    ...
}


What I have tried:

I've tried to use the builtin system, but no luck. I couldn't obtain the Context.User in OnConnected method. As a workaround, I've tried to send the username and password in header and validate them, but the OnConnected method cannot throw errors to client. I am sure the client has to have an auth cookie, but I really don't know how to add it.
Posted
Updated 20-Feb-16 0:16am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900