我使用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