【问题标题】:SignalR - authenticate windows forms user on windows forms serverSignalR - 在 Windows 窗体服务器上验证 Windows 窗体用户
【发布时间】:2016-02-18 18:39:40
【问题描述】:

我有一个小项目,其中包含一个 Windows 窗体 Signalr 客户端和一个 Windows 窗体服务器。客户端可以连接到服务器。现在,我想实现一个登录系统。我阅读了一些关于此的博客文章、文章和问题,但我没有找到解决方法。我想使用信号器身份验证系统,因此我可以使用 [Authorize] 等属性,因为它已经存在。

要使用它,我需要验证用户名和密码。客户端可以像这样在标头中发送凭据吗

Connection = new HubConnection(BaseEngine.ServerURI);
Connection.Headers.Add("Username", username);
Connection.Headers.Add("Password", password);
HubProxy = Connection.CreateHubProxy("ChatHub");
await Connection.Start();

服务器应该以某种方式验证这些凭据,如果无效则抛出异常?

我尝试过使用内置系统,但没有成功。我无法在 OnConnected 方法中获取 Context.User。作为一种解决方法,我尝试在标头中发送用户名和密码并验证它们,但 OnConnected 方法不能向客户端抛出错误。我确信客户端必须有一个 auth cookie,但我真的不知道如何添加它。

谢谢!

【问题讨论】:

    标签: c# windows forms signalr


    【解决方案1】:

    以这种方式向服务器发送密码从来都不是一个好主意,最好发送一个服务器可以验证的令牌。

    SignalR 还具有一些身份验证功能,请阅读有关此here 的更多信息

    【讨论】:

    • 嗨!我将密码发送到加密的服务器。作为一种解决方法,标题中包含用户名、密码和设备 ID 之间的组合,全部加密。我从您发布的链接中阅读了所有内容,但我没有找到任何方法来创建该 cookie。客户端是 Windows 窗体应用程序,服务器也是,而不是 asp.net 网站。
    【解决方案2】:

    我找到了类似的解决方法:首先,我实现了一个属性,该属性派生自 SignalR 使用的 AuthorizeAttribute。此实现覆盖 AuthorizeHubMethodInvocation 方法,当调用使用此属性装饰的方法时,将调用该方法。因此,在此方法中,我正在检查请求标头中是否存在授权令牌并验证信息。客户端必须添加此标头才能连接到服务器。这是迄今为止我发现的最简单的方法,但它仍然是一种解决方法。

    实现,服务器:

    [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(';');
    
                string userName = values[0],
                    deviceId = values[1];
    
                bool b = ...check if it's ok...
    
                return b;
            }
        }
    }
    

    实施,客户:

     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)
     {
         ...
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多