2013-01-04 198 views
5

我在Asp.Net之上創建了一個ServiceStack服務,該服務實現了基本身份驗證。在服務路線上一切正常。我可以登錄,並獲得會話cookie,這些cookie在隨後的調用中得到驗證。我爲這些請求使用HttpClient。使用ServiceStack身份驗證插件對SignalR Hub進行身份驗證

我也有一個SignalR Hub,它運行在同一個Asp.Net服務上,但是Principal沒有在我的Hub方法上進行驗證。

基本上我需要的是ServiceStack攔截到我的集線器的呼叫和驗證會話cookie並填充Context.User.Identity並將其標記爲已驗證。如果我可以完成設置,我的集線器上的一個簡單的[授權]屬性將完成剩下的工作。

這裏是我的代碼示例:

// set up a HttpClient with a cookie container to hold the session cookie 
var cookieJar = new CookieContainer(); 
var handler = new HttpClientHandler { CookieContainer = cookieJar, UseCookies = true, UseDefaultCredentials = false }; 

var client = new HttpClient(handler) { BaseAddress = _baseUri }; 

client.DefaultRequestHeaders.Authorization = 
new AuthenticationHeaderValue("Basic", 
    Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password)))); 

// do client login and get response with session cookie... 
var response = client.PostAsync(...); 

// add the cookies to the SignalR hub connection 
var responseCookies = cookieJar.GetCookies(_baseUri); 
var cookieContainer = new CookieContainer(); 
foreach (Cookie cookie in responseCookies) 
{ 
    cookieContainer.Add(cookie); 
} 
_hubConnection = new HubConnection(_baseUri.ToString()) { CookieContainer = cookieContainer }; 

此設置後,我的會話cookie被髮送到集線器上的每個調用。不知何故,我需要ServiceStack攔截這些請求並設置經過身份驗證的用戶。

回答

6

讓ServiceStack進行認證並保持用戶會話。然後在需要認證SignalR樞紐端點把這個代碼:

var cache = AppHostBase.Resolve<ICacheClient>(); 
var sess = cache.SessionAs<AuthUserSession>(); 
if (!sess.IsAuthenticated) 
    throw new AuthenticationException(); 
+0

這與我原來發布的代碼一起工作,我將auth cookie保存到SignalR cookie容器。謝謝! – Kevin

2

約翰的回答的作品,但它是不是很方便的把這個代碼的每一個方法,如果你把它放在中心的構造,它會在失敗頁面上的網頁刷新爲「僅支持通過單身人士訪問的ASP.NET請求」異常。

取而代之,我選擇了創建一個自定義屬性,使您可以更好地控制集線器和方法調用授權。

最簡單的屬性應該是這樣的:

[AttributeUsage(AttributeTargets.Class, Inherited = false)] 
public class AuthorizeServiceStack : AuthorizeAttribute 
{ 
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
    { 
     return CheckAuthorization(); 
    } 

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod) 
    { 
     return CheckAuthorization(); 
    } 

    private static bool CheckAuthorization() 
    { 
     var cache = AppHostBase.Resolve<ICacheClient>(); 
     var sess = cache.SessionAs<AuthUserSession>(); 
     return sess.IsAuthenticated; 
    } 

} 

正如你看到的,代碼是相同約翰的答案,但它會在網頁以及工作,確保HttpContext.Current不爲空當你調用cache.SessionAs

相關問題