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

调用.AddIdentityServerAuthentication()引发System.IO.IOException异常的问题

问题核心原因

你遇到的2分钟断连问题是弃用的AddIdentityServerAuthentication包的默认验证缓存逻辑导致的:该包是IdentityServer4早年针对.NET Core 2.1推出的认证集成包,早已停止维护,默认开启了2分钟有效期的令牌验证缓存。缓存过期时会自动向IdentityServer发起令牌内省请求,但SignalR是长连接,建立连接后不会再携带新的认证令牌,验证失败就会触发服务端主动断开WebSocket连接,抛出你看到的Socket异常。

可行解决方案

方案1(推荐):替换为官方标准AddJwtBearer配置

废弃不再维护的AddIdentityServerAuthentication,改用ASP.NET Core官方原生的JWT认证配置,完美兼容新版本SignalR长连接逻辑:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://myidentityserver.com/";
        options.RequireHttpsMetadata = true;
        options.Audience = "MyApi";
        // 适配SignalR从查询字符串取令牌的需求
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = context =>
            {
                var accessToken = context.Request.Query["access_token"];
                // 替换为你实际的SignalR Hub路由前缀
                if (!string.IsNullOrEmpty(accessToken) && context.HttpContext.Request.Path.StartsWithSegments("/hubs/yourHubName"))
                {
                    context.Token = accessToken;
                }
                return Task.CompletedTask;
            }
        };
    });

方案2(临时兼容):关闭令牌验证缓存

如果暂时无法替换旧包,直接在AddIdentityServerAuthentication配置中关闭默认开启的缓存即可解决2分钟断连问题:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://myidentityserver.com/";
                options.TokenRetriever = CustomTokenRetriever.FromHeaderAndQueryString;
                options.RequireHttpsMetadata = true;
                options.ApiName = "MyApi";
                // 新增这行关闭验证缓存
                options.EnableCaching = false;
            });

可选优化配置

可同步调整SignalR的心跳和超时参数,避免网络波动叠加导致意外断连:

services.AddSignalR(options =>
{
    // 心跳间隔调整为30秒
    options.KeepAliveInterval = TimeSpan.FromSeconds(30);
    // 客户端无响应超时调整为10分钟
    options.ClientTimeoutInterval = TimeSpan.FromMinutes(10);
});

另外注意后台任务调用IHubContext发消息时,直接使用分组的字符串名称操作,不要依赖已结束的HTTP请求的HttpContext.User对象,避免上下文释放导致的异常。

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:24:03