From 37156c937ad8b0999cb3eba1f8dcb5e0fc71a2a0 Mon Sep 17 00:00:00 2001 From: SikongJueluo Date: Wed, 13 Aug 2025 14:32:32 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DsignalR=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=AE=A4=E8=AF=81=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/Program.cs | 31 +++++++++++++++++++ .../src/Controllers/VideoStreamController.cs | 6 ++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/server/Program.cs b/server/Program.cs index b3c015e..c5fbe28 100644 --- a/server/Program.cs +++ b/server/Program.cs @@ -64,6 +64,37 @@ try }; options.Authority = $"http://{Global.LocalHost}:5000"; options.RequireHttpsMetadata = false; + + // We have to hook the OnMessageReceived event in order to + // allow the JWT authentication handler to read the access + // token from the query string when a WebSocket or + // Server-Sent Events request comes in. + + // Sending the access token in the query string is required when using WebSockets or ServerSentEvents + // due to a limitation in Browser APIs. We restrict it to only calls to the + // SignalR hub in this code. + // See https://docs.microsoft.com/aspnet/core/signalr/security#access-token-logging + // for more information about security considerations when using + // the query string to transmit the access token. + 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/JtagHub") || + path.StartsWithSegments("/hubs/ProgressHub") + )) + { + // Read the token out of the query string + context.Token = accessToken; + } + return Task.CompletedTask; + } + }; }); // Add JWT Token Authorization Policy builder.Services.AddAuthorization(options => diff --git a/server/src/Controllers/VideoStreamController.cs b/server/src/Controllers/VideoStreamController.cs index 0c23365..33820ae 100644 --- a/server/src/Controllers/VideoStreamController.cs +++ b/server/src/Controllers/VideoStreamController.cs @@ -11,6 +11,7 @@ using server.Services; /// [ApiController] [Authorize] +[EnableCors("Users")] [Route("api/[controller]")] public class VideoStreamController : ControllerBase { @@ -64,7 +65,6 @@ public class VideoStreamController : ControllerBase /// /// 服务状态信息 [HttpGet("ServiceStatus")] - [EnableCors("Users")] [ProducesResponseType(typeof(VideoStreamServiceStatus), StatusCodes.Status200OK)] [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public IResult GetServiceStatus() @@ -85,7 +85,6 @@ public class VideoStreamController : ControllerBase } [HttpGet("MyEndpoint")] - [EnableCors("Users")] [ProducesResponseType(typeof(VideoStreamEndpoint), StatusCodes.Status200OK)] [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public IResult MyEndpoint() @@ -109,7 +108,6 @@ public class VideoStreamController : ControllerBase /// /// 连接测试结果 [HttpPost("TestConnection")] - [EnableCors("Users")] [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)] [ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)] public async Task TestConnection() @@ -143,6 +141,8 @@ public class VideoStreamController : ControllerBase } [HttpPost("SetVideoStreamEnable")] + [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)] public async Task SetVideoStreamEnable(bool enable) { try