.NET Core 3.1 SignalR WebSocket AllowedOrigins通配符配置可行吗?
问题分析与解决方案
在.NET Core 3.1中,WebSocketOptions.AllowedOrigins不支持通配符匹配,你尝试的https://*.exampledomain.com这类写法不会生效——该属性仅接受完整、精确匹配的Origin值。针对多租户场景下无法逐个添加子域名的问题,有两种规范的解决方式:
1. 自定义WebSocket Origin验证逻辑
直接通过WebSocketOptions.OriginValidator委托实现自定义Origin校验逻辑,替代默认的AllowedOrigins精确匹配。示例代码如下:
services.AddWebSocketManager(options => { options.OriginValidator = (origin, context) => { // 允许无Origin头的请求(如同域请求) if (string.IsNullOrEmpty(origin)) return true; // 解析Origin并验证主机名 if (Uri.TryCreate(origin, UriKind.Absolute, out var originUri)) { var host = originUri.Host; // 匹配主域名或任意子域名 return host.Equals("exampledomain.com", StringComparison.OrdinalIgnoreCase) || host.EndsWith(".exampledomain.com", StringComparison.OrdinalIgnoreCase); } // 无法解析的Origin直接拒绝 return false; }; });
2. 为SignalR配置自定义CORS策略
由于SignalR依赖CORS机制处理跨域请求,你可以直接在CORS策略中实现动态Origin验证,覆盖WebSocket层面的检查,更贴合SignalR的使用场景:
// 注册自定义CORS策略 services.AddCors(options => { options.AddPolicy("SignalRCorsPolicy", policy => { policy.SetIsOriginAllowed(origin => { if (string.IsNullOrEmpty(origin)) return true; if (Uri.TryCreate(origin, UriKind.Absolute, out var uri)) { var host = uri.Host; return host.Equals("exampledomain.com", StringComparison.OrdinalIgnoreCase) || host.EndsWith(".exampledomain.com", StringComparison.OrdinalIgnoreCase); } return false; }) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); // 配置SignalR services.AddSignalR(); // 中间件启用顺序:先CORS,再SignalR app.UseCors("SignalRCorsPolicy"); app.UseSignalR(routes => { routes.MapHub<YourHub>("/your-hub-path"); });
关于临时方案的说明
你当前通过劫持中间件检查Origin的临时方案是可行的,但上述两种方法属于.NET Core官方支持的扩展方式,更具可维护性和规范性。
内容的提问来源于stack exchange,提问作者Uncle Jesse
相关产品推荐
相关产品推荐

