You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止不同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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:12:41