如何阻止不同HTTP方法调用SignalR的/signalr/negotiate端点并控制特定方法的授权访问?
控制SignalR /signalr/negotiate端点的HTTP方法访问权限
当然可以实现你的需求!不管是限制允许的HTTP方法,还是给特定方法添加授权验证,都有对应的解决方案。下面分场景给你具体实现方式:
1. 仅允许GET方法访问negotiate端点
SignalR的协商端点默认主要处理GET请求,所以直接拦截其他方法是最直接的方式。根据你使用的.NET版本,配置方式略有不同:
对于ASP.NET Core(包括.NET 5+)
在Program.cs中添加自定义中间件,放在SignalR配置之前:
// 先添加方法拦截中间件 app.Use(async (context, next) => { // 匹配negotiate端点路径 if (context.Request.Path.StartsWithSegments("/signalr/negotiate")) { // 只允许GET方法 if (!context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)) { context.Response.StatusCode = StatusCodes.Status405MethodNotAllowed; await context.Response.WriteAsync("Method Not Allowed: Only GET requests are permitted for /signalr/negotiate"); return; } } // 放行符合要求的请求 await next(); }); // 再配置SignalR app.MapHub<YourHubClass>("/signalr");
对于ASP.NET Framework(OWIN SignalR)
在Startup.cs的Configuration方法中,给SignalR路由添加中间件拦截:
public void Configuration(IAppBuilder app) { app.Map("/signalr", map => { // 添加方法拦截逻辑 map.Use((context, next) => { if (context.Request.Path.Value.EndsWith("/negotiate", StringComparison.OrdinalIgnoreCase)) { if (!context.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase)) { context.Response.StatusCode = 405; context.Response.ReasonPhrase = "Method Not Allowed"; return Task.CompletedTask; } } return next(); }); // 配置SignalR var hubConfig = new HubConfiguration(); map.RunSignalR(hubConfig); }); }
2. 为特定方法(如DELETE)添加授权验证
如果需要让DELETE等方法仅对授权用户开放,而GET方法无需授权,可以在中间件中加入身份验证逻辑:
ASP.NET Core示例
app.Use(async (context, next) => { if (context.Request.Path.StartsWithSegments("/signalr/negotiate")) { var requestMethod = context.Request.Method.ToUpperInvariant(); // 允许GET方法无需授权 if (requestMethod == "GET") { await next(); return; } // 对DELETE等其他方法要求授权 if (!context.User.Identity.IsAuthenticated) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; await context.Response.WriteAsync("Unauthorized: Authentication required for this method"); return; } // 可选:进一步检查用户角色或声明 if (!context.User.IsInRole("Admin")) { context.Response.StatusCode = StatusCodes.Status403Forbidden; await context.Response.WriteAsync("Forbidden: Admin role required for this method"); return; } } await next(); }); // 确保身份验证中间件已添加(如UseAuthentication、UseAuthorization) app.UseAuthentication(); app.UseAuthorization(); app.MapHub<YourHubClass>("/signalr");
注意事项
- 如果你使用的是ASP.NET Core SignalR的新版本,默认端点路径是
/hubs/{hubName}/negotiate,需要根据实际路径调整中间件的匹配规则。 - 拦截非GET方法时,返回405状态码是符合HTTP规范的,客户端会明确收到方法不允许的提示。
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

