我使用SignalR JavaScript客户端和ASP.NET的ServiceHost。我需要SignalR集线器和回调才能被登录用户访问。我还需要能够使用从HttpContext.Current.User的FormsIdentity集线器获得当前登录身份的用户。确保SignalR呼吁
- 如何确保集线器的安全,以便只有经过验证的用户才能使用SignalR?
- 我如何在从集线器当前登录用户的身份?
我使用SignalR JavaScript客户端和ASP.NET的ServiceHost。我需要SignalR集线器和回调才能被登录用户访问。我还需要能够使用从HttpContext.Current.User的FormsIdentity集线器获得当前登录身份的用户。确保SignalR呼吁
您应该使用可从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: 这可能是更好的,只是返回消息
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";
}
好,现在任何想法如何安全的集线器,以便未经身份验证的用户无法连接? – reach4thelasers 2012-04-03 14:52:42
@ reach4thelasers请参阅我的编辑。这就是我会尝试的。 – Aligned 2012-04-03 15:27:03
在看了下面的@Jared Kells的答案之后,我建议如果你需要强制认证所有的方法来使用他的方法,但是如果你只需要几种方法,那么就使用我的方法。 – Aligned 2012-10-30 14:04:29
您可以锁定SignalR URL的使用PostAuthenticateRequest事件在你的HttpApplication上。以下添加到您的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.User.Identity.Name
对于你的问题的一部分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);
}
}
东西从其他的答案缺少的是使用SignalR内置的定制能力auth类。在话题的实际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,因为在我的验证的HttpModule我已经authenicate的/ signalr/connect和/ signalr/reconnect调用并将用户数据保存在HttpContext项目中。因此,模块处理验证初始SignalR连接呼叫(一个标准的HTTP调用发起网络套接字连接)。
授权调用特定的集线器方法我根据保存在HttpContext中的权限(它与初始连接请求保存的是相同的HttpContext)检查方法名,并根据用户是否有权调用某个特定的方法。
在你的情况下,你可能实际上使用AuthorizeHubConnection方法并用特定角色装饰你的hub方法,因为它看起来像你使用的是标准化的身份系统,但如果某些东西不能正常工作,你总是可以恢复用HttpModule(或OWIN)中间件强行使用AuthorizeHubMethodInvocation在随后的websocket调用中查找上下文数据。
使用signalr 1.0和Owin锁定signalr url的另一种方法:http://eworldproblems.mbaynton.com/2012/12/securing-signalr-to-your-sites-users/ – mbaynton 2012-12-22 21:26:15