2013-01-04 158 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

相关问题