我在Asp.Net上创建了一个ServiceStack服务,它实现了基本身份验证。在服务路线上一切正常。我能够登录并获得会话cookie,这些cookie在后续呼叫中得到验证。我正在使用HttpClient来处理这些请求。
我还有一个在同一个Asp.Net服务上运行的SignalR Hub,但是我的Hub方法没有对Principal进行身份验证。
基本上我需要的是ServiceStack拦截到我的Hub的调用并验证会话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来拦截这些请求并设置经过身份验证的用户。
答案 0 :(得分:6)
让ServiceStack进行身份验证并持久保存用户会话。然后在需要身份验证的SignalR集线器端点中输入以下代码:
var cache = AppHostBase.Resolve<ICacheClient>();
var sess = cache.SessionAs<AuthUserSession>();
if (!sess.IsAuthenticated)
throw new AuthenticationException();
答案 1 :(得分:2)
Johan的回答是有效的,但是将这些代码放在每个方法上并不是很方便,如果你把它放在集线器构造函数中,它将在页面刷新时使用&#34; Only ASP失败。支持通过单身人士访问的NET请求&#34;异常。
相反,我选择创建一个自定义属性,使您可以更好地控制集线器和方法调用授权。
最简单的属性如下所示:
[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;
}
}
正如您所看到的,代码与Johan的答案相同,但它也适用于Web,确保在调用cache.SessionAs时HttpContext.Current不为null