我正在尝试使用 OpenIddict 在 .Net Core 8 中设置 SignalR 服务器进行身份验证。但是,当我尝试使用客户端应用程序进行连接时,我不断收到错误。
我最初使用 this 包在 Flutter 中设置了一个 SignalR 客户端(这意味着成为一个聊天应用程序),但不断收到以下错误:
WebSocketException: Connection to 'https://localhost:7167/chat?id=7jBaqym0ZCsx3BFNkROuAg&access_token=<my-token># was not upgraded to websocket'
...
The underlying connection was closed before the hub handshake could complete.
我最终只是尝试使用 Postman 进行 WebSocket 请求,但我现在在标题中收到错误,没有其他信息。
如果我包含“id”查询参数:
Could not connect to wss://localhost:7167/chat?id=MlUKLB8YmTPVsPLN5X5-ug&access_token=<my-token>
Error: Unexpected server response: 400
如果我不包含“id”参数:
Could not connect to wss://localhost:7167/chat?access_token=<my-token>
Error: Unexpected server response: 200
(使用
{"protocol":"json","version":1}
作为消息正文)
我在服务器上获得的唯一日志来自 OpenIddict(我认为)成功验证了请求,但没有来自 SignalR 的日志。
我已经尝试了网上发布的几乎所有解决方案,但似乎没有任何效果,甚至给我带来其他错误。我也在 Flutter 方面尝试了几种不同的插件,因为似乎有多种不同的选项。
我的服务器的
Program.cs
看起来像这样:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR(options =>
{
options.EnableDetailedErrors = true;
options.DisableImplicitFromServicesParameters = true;
});
builder.Services.AddSingleton<IUserIdProvider, UserIdProvider>();
builder.Services.AddOpenIddict()
.AddValidation(builder =>
{
builder.SetIssuer("<my-auth-url>");
builder.AddAudiences("<my-client-id>");
builder.UseIntrospection()
.SetClientId("<my-client-id>")
.SetClientSecret("<my-secret>");
builder.UseSystemNetHttp();
builder.UseAspNetCore();
});
builder.Services.AddAuthentication(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);
builder.Services.AddAuthorization();
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, ConfigureJwtBearerOptions>());
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<ChatHub>("chat");
app.Run();
我的中心看起来像这样:
[Authorize]
public class ChatHub(
ILogger<ChatHub> logger) : Hub<IChatClient>
{
public async Task SendMessage(string message)
{
await Clients.All.ReceiveMessage(Context.UserIdentifier, message);
}
}
我还想提一下,服务器和 Flutter 应用程序都在我的计算机上本地运行。
任何帮助将不胜感激。谢谢。
我已经找到答案了。
当试图弄清楚我的 API 布局时,我制作了一个控制器,我计划用它来获取聊天历史记录。
我称它为
ChatController
,用属性[Route("[controller]")]
装饰它,然后很快就忘记了它。
这当然与我的 Hub 的路由冲突。