Asp.net 是否可以使用HttpModule对信号器进行身份验证

Asp.net 是否可以使用HttpModule对信号器进行身份验证,asp.net,authentication,signalr,owin,httpmodule,Asp.net,Authentication,Signalr,Owin,Httpmodule,我正在开发一个应用程序,它使用HttpModule执行自定义身份验证和授权。我的问题是HttpModule中设置的用户标识在Signal上下文对象中不可访问 在自定义身份验证逻辑之后,我在HttpModule BeginRequest处理程序中执行以下操作: var userClaims = new List<Claim>(); userClaims.Add(new Claim(ClaimTypes.NameIdentifier, <some id>)); userCla

我正在开发一个应用程序,它使用HttpModule执行自定义身份验证和授权。我的问题是HttpModule中设置的用户标识在Signal上下文对象中不可访问

在自定义身份验证逻辑之后,我在HttpModule BeginRequest处理程序中执行以下操作:

var userClaims = new List<Claim>();
userClaims.Add(new Claim(ClaimTypes.NameIdentifier, <some id>));
userClaims.Add(new Claim(ClaimTypes.Name, <some name>));
userClaims.Add(new Claim(ClaimTypes.Email, <da email>));
userClaims.Add(new Claim(ClaimTypes.Authentication, "true"));

var id = new ClaimsIdentity(userClaims);
var principal = new ClaimsPrincipal(new[] { id });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
因此,我的计划是从AuthorizeHubMethodInvocation方法中访问hubContext.Hub.Context.User变量,以执行我需要的任何自定义授权。但是,它只包含默认的WindowsPrincipal

如果我查看AuthorizeHubConnection调用(实际上是一个常规HTTP请求,而不是websocket调用),我会看到HttpContext.Current对象也没有像它应该的那样设置用户

我确实看到我可以访问HttpContext.Current.Items集合。我想我可以用它把主体从模块中扔到信号器上下文中,但我不确定这是我应该做的


简单地将HttpModule重写为OWIN中间件是否最好?如果我们升级到ASP.NET 5,我似乎无论如何都得换东西;没有什么比微软产品更能给你提供工作保障。

我忘了我刚才发布了这个问题。最后,我在评论微软的文章时解释了我的解决方案。在尝试为auth实现OWIN中间件之后,我发现我必须进行一些愚蠢的配置来运行所有请求的所有模块,这是低效的。我不知道如何为所有请求只运行Auth OWIN中间件组件,所以我放弃了这种方法,继续使用我的HttpModule。以下是我在上面链接的页面上发布的针对SignalR auth的解决方案摘要:

1) 创建一个AuthorizeAttribute类,如本文所示:

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class CustomAuthAttribute : AuthorizeAttribute
2) 用您创建的auth类装饰您的Hub类。命名约定似乎是auth类本身的(SomeName)属性和中心装饰的(SomeName)属性

[CustomAuth]
public class ServerWebSocket : Hub
3) 不要覆盖文档中显示的“UserAuthorized”方法,而是覆盖以下方法(我是从其他SO帖子中获得的,但我现在找不到):

为了实际授权用户,我在HttpModule中捕获信号器连接请求,并在HttpContext项集合中设置一项,如下所示:

if (req.Path.StartsWith("/signalr/connect") || req.Path.StartsWith("/signalr/reconnect"))
{
    var user_info = doFullAuth(<some token>);
    HttpContext.Current.Items.Add("userDat", user_info);
}
if(请求路径StartsWith(“/signalr/connect”)| |请求路径StartsWith(“/signalr/reconnect”))
{
var user_info=doFullAuth();
HttpContext.Current.Items.Add(“userDat”,用户信息);
}
这实际上是为了在用户没有权限的情况下,在HttpModule中完全拒绝连接请求而设置的。所以我实际上根本没有实现signarauth方法“AuthorizeHubConnection”。但是在“AuthorizeHubMethodInvocation”方法中,我通过调用在原始连接请求上设置的HttpContext.Current.Items来访问用户数据,并执行自定义逻辑以确定用户是否可以访问方法

如果您想对每个请求进行身份验证以保护静态文件等,这是我能想到的使其工作的最佳方法

public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubContext, bool appliesToMethod)
if (req.Path.StartsWith("/signalr/connect") || req.Path.StartsWith("/signalr/reconnect"))
{
    var user_info = doFullAuth(<some token>);
    HttpContext.Current.Items.Add("userDat", user_info);
}