我有一个带有表单身份验证的Web服务器和另一个托管SignalR Hub的服务器。使用表单身份验证cookie我想使用下面的代码提取当前用户。这可以使用HttpModule,但是当使用SignalR时,不能使用HttpModule。
有没有其他方法可以归档我想要做的事情?
public class AuthorizationHubModule : HubPipelineModule
{
public AuthorizationHubModule()
{
}
protected override bool OnBeforeConnect(IHub hub)
{
var cookies = hub.Context.Request.Cookies;
if (cookies.ContainsKey(".ASPXAUTH") == true)
{
// Get the user, populate the Thread.CurrentUser...
Cookie cookie = cookies[".ASPXAUTH"];
if (cookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
GenericIdentity identity = new GenericIdentity(ticket.Name);
GenericPrincipal principal = new GenericPrincipal(identity, new string[0]);
// Cannot do this because User is readonly (this is possible in a normal HttpModule)
//hub.Context.User = principal;
}
}
return base.OnBeforeConnect(hub);
}
}
我们追求的是设置与SignalR相关联的IPrincipal。
答案 0 :(得分:1)
如果我没弄错的话,你试图从上下文中提取登录用户的用户信息。如果这是正确的,可以通过执行以下操作简单地实现:
由于您使用的是持久连接,因此需要由您处理授权过程。请参阅this link,您可以根据需要调整其中提供的代码。
要更改请求的标识,您必须将FormsAuthentication_OnAuthenticate添加到global.asax。这是我为我的应用程序编写的示例代码:
protected void FormsAuthentication_OnAuthenticate(Object sender, FormsAuthenticationEventArgs e)
{
if (FormsAuthentication.CookiesSupported == true)
{
if (Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
try
{
string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name;
//Let us set the Pricipal with our user specific details
e.User = new System.Security.Principal.GenericPrincipal(
new System.Security.Principal.GenericIdentity(username, "Forms"), _user.GetUserRoles(username));
}
catch (Exception)
{
//somehting went wrong
}
}
}
}
希望这有帮助。
答案 1 :(得分:1)
事实证明,Signal-R无法修改相关的IPrincipal,因为SignalR不是为了进行身份验证,而是从应用程序获取身份验证上下文。因此,正如@Shashank指出的那样,正确的方法是使用表单或您在应用程序中使用的任何内容,而SignalR将从中获取此上下文。
答案 2 :(得分:0)
实施界面IUserIdProvider
并使用
GlobalHost.Configuration.Resolver.Register(typeof(IUserIdProvider), () => provider.Object);
您可以阅读更多here。