SignalR 在对某些用户使用 WebSockets 或 ServerSentEvents 时给出 404,但对其他用户则不
SignalR gives 404 when using WebSockets or ServerSentEvents for some users but not for others
SignalR 在尝试连接某些用户时给我 404。除 access_token.
外,URL 相同
每个用户都稳定可复现(我的意思是有的用户稳定OK,有的用户稳定404)。
access_token 已解析的 jwt diff(左边是 OK 用户,右边是 404):
我对日志进行了跟踪级别的跟踪,接下来是:
对于 OK 用户:
对于收到 404 的用户:
注意:黑色方块下的网址是相同的。
前端是 Angular 9 包 "@microsoft/signalr": "^3.1.8"
,这里是建立连接的代码:
private buildHub(): HubConnection {
console.log(this.authService.accessToken);
let builder = new HubConnectionBuilder()
.withAutomaticReconnect()
.configureLogging(LogLevel.Information)
.withUrl('ws/notificationHub', {
accessTokenFactory: () => this.authService.accessToken
});
if (this.debugMode) {
builder = builder.configureLogging(LogLevel.Trace);
}
return builder.build();
}
后端正在使用启动中的下一个代码来配置 signalR hub:
在public void ConfigureServices(IServiceCollection services)
中:
services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
});
在public void Configure(IApplicationBuilder app, IHostingEnvironment env)
中:
app.UseSignalR(route =>
{
route.MapHub<NotificationHub>("/ws/notificationHub");
});
我们还使用自定义身份验证,因此我们有 Authorize
集线器属性 class:
[Authorize]
public class NotificationHub: Hub<INotificationHubClient>
和 public void ConfigureServices(IServiceCollection services)
中的代码:
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = identityServerSettings.Url;
options.Audience = identityServerSettings.ApiScopeName;
options.RequireHttpsMetadata = identityServerSettings.RequireHttpsMetadata;
options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/ws"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
不幸的是,我没有完全访问可重现环境的权限,但我可以请求查看任何设置或尝试进行一些更改。
我还能尝试什么来解决问题?
更新: 协商对两个用户都很好。
最近,在我的 JWT 大小增加后,我遇到了这个问题。我发现在我的案例中,IIS 抛出了 404 错误,因为查询字符串超过了 2048 的限制。增加查询字符串最大长度后,我的问题得到解决。
SignalR 在尝试连接某些用户时给我 404。除 access_token.
外,URL 相同每个用户都稳定可复现(我的意思是有的用户稳定OK,有的用户稳定404)。
access_token 已解析的 jwt diff(左边是 OK 用户,右边是 404):
我对日志进行了跟踪级别的跟踪,接下来是:
对于 OK 用户:
对于收到 404 的用户:
注意:黑色方块下的网址是相同的。
前端是 Angular 9 包 "@microsoft/signalr": "^3.1.8"
,这里是建立连接的代码:
private buildHub(): HubConnection {
console.log(this.authService.accessToken);
let builder = new HubConnectionBuilder()
.withAutomaticReconnect()
.configureLogging(LogLevel.Information)
.withUrl('ws/notificationHub', {
accessTokenFactory: () => this.authService.accessToken
});
if (this.debugMode) {
builder = builder.configureLogging(LogLevel.Trace);
}
return builder.build();
}
后端正在使用启动中的下一个代码来配置 signalR hub:
在public void ConfigureServices(IServiceCollection services)
中:
services.AddSignalR()
.AddJsonProtocol(options =>
{
options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
});
在public void Configure(IApplicationBuilder app, IHostingEnvironment env)
中:
app.UseSignalR(route =>
{
route.MapHub<NotificationHub>("/ws/notificationHub");
});
我们还使用自定义身份验证,因此我们有 Authorize
集线器属性 class:
[Authorize]
public class NotificationHub: Hub<INotificationHubClient>
和 public void ConfigureServices(IServiceCollection services)
中的代码:
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = identityServerSettings.Url;
options.Audience = identityServerSettings.ApiScopeName;
options.RequireHttpsMetadata = identityServerSettings.RequireHttpsMetadata;
options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/ws"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
不幸的是,我没有完全访问可重现环境的权限,但我可以请求查看任何设置或尝试进行一些更改。
我还能尝试什么来解决问题?
更新: 协商对两个用户都很好。
最近,在我的 JWT 大小增加后,我遇到了这个问题。我发现在我的案例中,IIS 抛出了 404 错误,因为查询字符串超过了 2048 的限制。增加查询字符串最大长度后,我的问题得到解决。