.NET 6中SignalR客户端连接Hub前执行自定义逻辑的方法
.NET 6 SignalR 连接前自定义逻辑实现方案
首先澄清:.NET 6 的 SignalR 是支持 IHubFilter 的,它位于 Microsoft.AspNetCore.SignalR.Filters 命名空间下,你可以通过以下几种方式实现类似 [Authorize] 的自定义连接前逻辑:
方案一:使用 IHubFilter 实现全局/局部拦截
IHubFilter 可以全局或针对特定 Hub 拦截连接、方法调用等生命周期事件,适合统一处理多个 Hub 的自定义逻辑。
1. 实现自定义 IHubFilter
using Microsoft.AspNetCore.SignalR.Filters; public class CustomConnectionFilter : IHubFilter { // 拦截连接建立事件 public async Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next) { // 获取请求上下文,用于获取头信息、用户数据等 var httpContext = context.Context.GetHttpContext(); // 执行自定义验证逻辑,比如校验自定义令牌 var customToken = httpContext.Request.Headers["X-Custom-Token"].FirstOrDefault(); if (string.IsNullOrEmpty(customToken) || !ValidateToken(customToken)) { // 验证失败时抛出异常,直接终止连接 throw new HubException("Invalid or missing custom token"); } // 验证通过后,继续执行默认连接流程 await next(context); } // 自定义令牌验证逻辑 private bool ValidateToken(string token) { // 替换为你的实际验证逻辑 return token == "your-valid-token"; } }
2. 注册 Filter
- 全局生效:在
Program.cs中全局注册,对所有 Hub 生效
builder.Services.AddSignalR(options => { options.AddFilter<CustomConnectionFilter>(); });
- 局部生效:仅对指定 Hub 生效,给 Hub 类添加特性
[HubFilter(typeof(CustomConnectionFilter))] public class ChatHub : Hub { // Hub 业务代码 }
方案二:重写 Hub 的 OnConnectedAsync 方法
如果仅需针对单个 Hub 实现自定义逻辑,直接重写 Hub 的 OnConnectedAsync 方法即可,在默认连接逻辑执行前加入你的代码:
public class ChatHub : Hub { public override async Task OnConnectedAsync() { // 连接前的自定义逻辑 var httpContext = Context.GetHttpContext(); var requiredHeader = httpContext.Request.Headers["X-Required-Header"].FirstOrDefault(); if (string.IsNullOrEmpty(requiredHeader)) { throw new HubException("Missing required header"); } // 执行默认连接流程 await base.OnConnectedAsync(); } }
方案三:自定义授权特性(权限场景)
如果你的自定义逻辑是权限验证相关,可以继承 AuthorizeAttribute 实现自定义授权规则,直接标记在 Hub 上:
public class CustomHubAuthorizeAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContext httpContext) { // 自定义授权逻辑,比如校验用户声明、角色等 var user = httpContext.User; return user.HasClaim("CustomPermission", "CanAccessSignalR"); } }
使用时直接标记 Hub:
[CustomHubAuthorize] public class ChatHub : Hub { // Hub 业务代码 }
注意:SignalR 连接的上下文可以通过
Context.GetHttpContext()获取请求头、用户身份等信息,WebSocket 连接会保留初始请求的头信息。
内容的提问来源于stack exchange,提问作者Misho Jikurashvili
相关产品推荐
相关产品推荐

