Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 如何在集线器外部的信号器核心中获取当前ClaimsPrincipal_Asp.net Core_Asp.net Core Signalr_Azure Signalr - Fatal编程技术网

Asp.net core 如何在集线器外部的信号器核心中获取当前ClaimsPrincipal

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

我知道,我可以使用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;
        }
    }
}