我正在使用SignalR Javascript客户端和ASP.NET ServiceHost。我需要SignalR集线器和回调才能被登录用户访问。我还需要能够使用HttpContext.Current.User中的FormsIdentity从Hub获取当前登录用户的身份。
答案 0 :(得分:19)
您应该使用Hub提供的this.Context.User.Identity
。 See a related question
编辑:停止未经身份验证的用户:
public void ThisMethodRequiresAuthentication()
{
if(!this.Context.User.Identity.IsAuthenticated)
{
// possible send a message back to the client (and show the result to the user)
this.Clients.SendUnauthenticatedMessage("You don't have the correct permissions for this action.");
return;
}
// user is authenticated continue
}
编辑#2:编辑#2:
这可能会更好,只需返回一条消息
public string ThisMethodRequiresAuthentication()
{
if(!this.Context.User.Identity.IsAuthenticated)
{
// possible send a message back to the client (and show the result to the user)
return "You don't have the correct permissions for this action.");
// EDIT: or throw the 403 exception (like in the answer from Jared Kells (+1 from me for his answer), which I actually like better than the string)
throw new HttpException(403, "Forbidden");
}
// user is authenticated continue
return "success";
}
答案 1 :(得分:14)
您可以使用HttpApplication上的PostAuthenticateRequest事件锁定SignalR URL。将以下内容添加到Global.asax.cs
这将阻止不使用“https”或未经过身份验证的请求。
public override void Init()
{
PostAuthenticateRequest += OnPostAuthenticateRequest;
}
private void OnPostAuthenticateRequest(object sender, EventArgs eventArgs)
{
if (Context.Request.Path.StartsWith("/signalr", StringComparison.OrdinalIgnoreCase))
{
if(Context.Request.Url.Scheme != "https")
{
throw new HttpException(403, "Forbidden");
}
if (!Context.User.Identity.IsAuthenticated)
{
throw new HttpException(403, "Forbidden");
}
}
}
在您的中心内,您可以通过Context对象访问当前用户。
Context.User.Identity.Name
答案 2 :(得分:4)
对于您的问题的第1部分,您可以使用如下注释(这适用于SignalR 1.1):
[Authorize]
public class MyHub : Hub
{
public void MarkFilled(int id)
{
Clients.All.Filled(id);
}
public void MarkUnFilled(int id)
{
Clients.All.UnFilled(id);
}
}
答案 3 :(得分:1)
其他答案中缺少的是能够使用SignalR的内置自定义身份验证类。关于该主题的实际SignalR文档非常糟糕,但我在页面底部留下了一条评论,详细说明了如何实际执行此操作(Authentication and Authorization for SignalR Hubs)。
基本上你覆盖了提供的SignalR AuthorizeAttribute类
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class CustomAuthAttribute : AuthorizeAttribute
然后使用类声明上方的[CustomAuth]装饰您的集线器。然后,您可以覆盖以下方法来处理身份验证:
bool AuthorizeHubConnection(HubDescriptor hubDesc, IRequest request);
bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubContext, bool appliesToMethod);
由于我在IIS服务器上并且有自定义身份验证方案,我只是从AuthorizeHubConnection方法返回true,因为在我的Auth HttpModule中我已经验证了/ signalr / connect和/ signalr / reconnect调用并保存了用户数据一个HttpContext项。因此,模块处理初始SignalR连接调用(启动Web套接字连接的标准HTTP调用)的身份验证。
要授权对特定集线器方法的调用,请根据HttpContext中保存的权限检查方法名称(它与初始连接请求中保存的HttpContext相同),并根据用户是否有权调用某个方法返回true或false
在您的情况下,您可能实际上可以使用AuthorizeHubConnection方法并使用特定角色装饰您的hub方法,因为它看起来像您正在使用标准化身份系统,但如果某些东西不能正常工作,您始终可以恢复到使用HttpModule(或OWIN)中间件进行暴力破解,并使用AuthorizeHubMethodInvocation在后续的websocket调用中查找上下文数据。