Asp.net core 如何在集线器外部的信号器核心中获取当前ClaimsPrincipal
我有一个信号核心集线器,它依赖于服务。该服务本身有自己的依赖项,其中一个依赖项需要访问当前的ClaimsPrincipal 我知道,我可以使用Context.User属性访问中心内的ClaimsPrincipal,并将其作为参数传递给服务,服务也可以将其作为参数传递,等等。但我真的不想通过将这种环境信息作为参数传递而污染服务API 我已尝试使用IHttpContextAccessor,如中所述: 这似乎适用于一个简单的信号器设置,但不适用于Azure信号器服务,这将是我们的生产设置Asp.net core 如何在集线器外部的信号器核心中获取当前ClaimsPrincipal,asp.net-core,asp.net-core-signalr,azure-signalr,Asp.net Core,Asp.net Core Signalr,Azure Signalr,我有一个信号核心集线器,它依赖于服务。该服务本身有自己的依赖项,其中一个依赖项需要访问当前的ClaimsPrincipal 我知道,我可以使用Context.User属性访问中心内的ClaimsPrincipal,并将其作为参数传递给服务,服务也可以将其作为参数传递,等等。但我真的不想通过将这种环境信息作为参数传递而污染服务API 我已尝试使用IHttpContextAccessor,如中所述: 这似乎适用于一个简单的信号器设置,但不适用于Azure信号器服务,这将是我们的生产设置 有没有一种可
有没有一种可靠的方法可以将ClaimsPrincipal从集线器外部获取,这种方法既适用于简单的本地设置,也适用于Azure Signal服务?在当前的Signal版本(1.1.0)中,不支持这种方法。我创建了一个功能请求:但被拒绝了。最终,我还是这样做的:
services.AddSingleton(typeof(HubDispatcher<>), typeof(HttpContextSettingHubDispatcher<>));
services.AddSingleton(typeof(HubDispatcher)、typeof(HttpContextSettingHubDispatcher));
公共类HttpContextSettingHubDispatcher:DefaultHubDispatcher其中THub:Hub
{
专用只读IHttpContextAccessor\u httpContextAccessor;
公共HttpContextSettingHubDispatcher(IServiceScopeFactory服务范围工厂,IHubContext hubContext,
IOptions HUBHOPTIONS,IOptions GLOBALHUBHOPTIONS,
ILogger记录器,IHttpContextAccessor httpContextAccessor):
基本(serviceScopeFactory、hubContext、hubOptions、globalHubOptions、logger)
{
_httpContextAccessor=httpContextAccessor;
}
公共覆盖异步任务OnConnectedAsync(HubConnectionContext连接)
{
等待InvokeWithContext(连接,()=>base.OnConnectedAsync(连接));
}
公共覆盖异步任务OnDisconnectedAsync(HubConnectionContext连接,异常)
{
等待InvokeWithContext(连接,()=>base.OnDisconnectedAsync(连接,异常));
}
公共覆盖异步任务DispatchMessageAsync(HubConnectionContext连接,HubMessage HubMessage)
{
开关(hubMessage)
{
案例调用消息:
案例流调用消息u:
等待InvokeWithContext(连接,()=>base.DispatchMessageAsync(连接,hubMessage));
打破
违约:
wait base.DispatchMessageAsync(连接,hubMessage);
打破
}
}
专用异步任务InvokeWithContext(HubConnectionContext连接,Func操作)
{
var=false;
if(_httpContextAccessor.HttpContext==null)
{
_httpContextAccessor.HttpContext=connection.GetHttpContext();
清除=真;
}
等待行动();
如果(清理)
{
_httpContextAccessor.HttpContext=null;
}
}
}
我遇到了同样的问题。到目前为止,我只找到了这个变通方法,在使用时遇到了麻烦。你安装了什么软件包?I get“HubConnectionContext”不包含“GetHttpContext”的定义
它位于此类中:nuget:Microsoft.AspNetCore.signal
public class HttpContextSettingHubDispatcher<THub> : DefaultHubDispatcher<THub> where THub : Hub
{
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextSettingHubDispatcher(IServiceScopeFactory serviceScopeFactory, IHubContext<THub> hubContext,
IOptions<HubOptions<THub>> hubOptions, IOptions<HubOptions> globalHubOptions,
ILogger<DefaultHubDispatcher<THub>> logger, IHttpContextAccessor httpContextAccessor) :
base(serviceScopeFactory, hubContext, hubOptions, globalHubOptions, logger)
{
_httpContextAccessor = httpContextAccessor;
}
public override async Task OnConnectedAsync(HubConnectionContext connection)
{
await InvokeWithContext(connection, () => base.OnConnectedAsync(connection));
}
public override async Task OnDisconnectedAsync(HubConnectionContext connection, Exception exception)
{
await InvokeWithContext(connection, () => base.OnDisconnectedAsync(connection, exception));
}
public override async Task DispatchMessageAsync(HubConnectionContext connection, HubMessage hubMessage)
{
switch (hubMessage)
{
case InvocationMessage _:
case StreamInvocationMessage _:
await InvokeWithContext(connection, () => base.DispatchMessageAsync(connection, hubMessage));
break;
default:
await base.DispatchMessageAsync(connection, hubMessage);
break;
}
}
private async Task InvokeWithContext(HubConnectionContext connection, Func<Task> action)
{
var cleanup = false;
if (_httpContextAccessor.HttpContext == null)
{
_httpContextAccessor.HttpContext = connection.GetHttpContext();
cleanup = true;
}
await action();
if (cleanup)
{
_httpContextAccessor.HttpContext = null;
}
}
}