SignalR 2.0中的授权

时间:2013-11-28 18:19:45

标签: asp.net authorization signalr signalr-hub

我有一个带有表单身份验证的Web服务器和另一个托管SignalR Hub的服务器。使用表单身份验证cookie我想使用下面的代码提取当前用户。这可以使用HttpModule,但是当使用SignalR时,不能使用HttpModule。

有没有其他方法可以归档我想要做的事情?

public class AuthorizationHubModule : HubPipelineModule
{
    public AuthorizationHubModule()
    {
    }

    protected override bool OnBeforeConnect(IHub hub)
    {
        var cookies = hub.Context.Request.Cookies;
        if (cookies.ContainsKey(".ASPXAUTH") == true)
        {
            // Get the user, populate the Thread.CurrentUser...
            Cookie cookie = cookies[".ASPXAUTH"];

            if (cookie != null)
            {
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

                GenericIdentity identity = new GenericIdentity(ticket.Name);
                GenericPrincipal principal = new GenericPrincipal(identity, new string[0]);

                // Cannot do this because User is readonly (this is possible in a normal HttpModule)
                //hub.Context.User = principal;
            }
        }

        return base.OnBeforeConnect(hub);
    }
}

我们追求的是设置与SignalR相关联的IPrincipal。

3 个答案:

答案 0 :(得分:1)

如果我没弄错的话,你试图从上下文中提取登录用户的用户信息。如果这是正确的,可以通过执行以下操作简单地实现:

  1. 将[授权]属性添加到您的集线器类。
  2. 然后使用Context.User.Identity获取用户身份。
  3. 由于您使用的是持久连接,因此需要由您处理授权过程。请参阅this link,您可以根据需要调整其中提供的代码。

    要更改请求的标识,您必须将FormsAuthentication_OnAuthenticate添加到global.asax。这是我为我的应用程序编写的示例代码:

    protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
        {
            if (FormsAuthentication.CookiesSupported == true)
            {
                if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
                {
                    try
                    {
                        string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
    
                        //Let us set the Pricipal with our user specific details
                        e.User = new System.Security.Principal.GenericPrincipal(
                          new System.Security.Principal.GenericIdentity(username, "Forms"), _user.GetUserRoles(username));                        
                    }
                    catch (Exception)
                    {
                        //somehting went wrong
                    }
                }
            }
        }
    

    希望这有帮助。

答案 1 :(得分:1)

事实证明,Signal-R无法修改相关的IPrincipal,因为SignalR不是为了进行身份验证,而是从应用程序获取身份验证上下文。因此,正如@Shashank指出的那样,正确的方法是使用表单或您在应用程序中使用的任何内容,而SignalR将从中获取此上下文。

答案 2 :(得分:0)

实施界面IUserIdProvider并使用

添加界面
GlobalHost.Configuration.Resolver.Register(typeof(IUserIdProvider), () => provider.Object);

您可以阅读更多here