WPF连接SignalR时Identity始终为空,API请求则正常,求排查
问题描述
开发了一个WPF应用用于连接SignalR API,遇到Identity相关问题:调用常规API端点(GET、POST、PUT、DELETE)时,Identity能正确填充所有声明;但连接SignalR时,Identity Claims却不存在。
后端JWT注册代码
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = configuration["Jwt:Issuer"], ValidAudience = configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:Key"])) }; options.Authority = configuration["Jwt:Authority"]; options.RequireHttpsMetadata = false; options.SaveToken = true; options.Events = new JwtBearerEvents() { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/hubs"))) { // Read the token out of the query string context.Token = accessToken; } return Task.CompletedTask; }, }; });
WPF端SignalR连接代码
_connection = new HubConnectionBuilder() .ConfigureLogging(logBuilder => { logBuilder.AddConsole(); logBuilder.AddDebug(); }) .WithUrl($"{url}/hubs", options => { options.AccessTokenProvider = _userService.GetToken;//returns Task.FromResult(userToken) }) .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(120) }) .Build();
JWT配置
"jwt":{ "Key":"some random generated key", "Issuer":"https://localhost:5001/", "Audience":"https://localhost:5001/", "Authority":"https://localhost:5001/" },
排查与修复方案
1. 移除冲突的JWT验证配置
你同时配置了TokenValidationParameters和Authority,这会导致验证逻辑冲突:
- 指定
Authority后,系统会启用OpenID Connect发现机制,忽略手动设置的签发者、受众和签名密钥 - 你的JWT是用自定义对称密钥生成的,并非来自
Authority指向的身份提供者,因此验证失败,Claims无法填充
修复操作:
删除options.Authority = configuration["Jwt:Authority"];这一行,保留手动配置的TokenValidationParameters即可,修改后的后端代码如下:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = configuration["Jwt:Issuer"], ValidAudience = configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:Key"])) }; options.RequireHttpsMetadata = false; options.SaveToken = true; options.Events = new JwtBearerEvents() { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs")) { context.Token = accessToken; } return Task.CompletedTask; }, }; });
2. 确认客户端Token有效性
检查_userService.GetToken返回的JWT是否有效:
- 用JWT解析工具验证Token包含所需的Claims
- 确认Token的签发者、受众与后端配置完全一致
- 确保Token未过期
3. 给Hub添加授权特性
如果你的SignalR Hub类没有添加[Authorize]特性,即使Token验证通过,Identity也不会被填充,需补充该特性:
[Authorize] public class YourHub : Hub { // Hub业务方法 }
4. 查看验证日志排查问题
在后端开启详细日志,定位JWT验证失败的具体原因:
在appsettings.json中添加日志配置:
"Logging": { "LogLevel": { "Microsoft.AspNetCore.Authentication": "Debug", "Microsoft.AspNetCore.SignalR": "Debug" } }
启动项目后查看日志,可获取Token验证过程中的错误信息(如签名不匹配、签发者错误等)。
内容的提问来源于stack exchange,提问作者3xGuy
相关产品推荐
相关产品推荐

