验证 sessionId 后设置为 userid 的作用域变量在信号器集线器内不可用

发布于 2025-01-17 03:11:26 字数 2157 浏览 1 评论 0原文

我试图通过将 sessionId 解析为 userId 并将其设置在作用域对象中来验证我的客户端。该代码能够进行身份验证,并且我将 userid 设置为作用域对象,但是当我尝试使用 DI 从 Hub 访问此作用域对象时,我没有得到作用域对象,而是一个新的对象目的。

这种身份验证方法适用于 API。

我的验证器代码

protected Scope Scope; // this is a custom class that stores userId along with some other params.

    public AuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock,
        Scope Scope)
        : base(options, logger, encoder, clock)
    {
        this.Scope = Scope;
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        Task<AuthenticateResult> Result = null;
        Task<AuthenticateResult> Failure = Task.FromResult(AuthenticateResult.Fail("not authorized"));

        try
        {
            var session = await GetSessionDetails(input);

            if (session == null)
            {
                return await Failure;
            }

            string Name = session.UserId;

            Scope.UserId = new Guid(session.UserId); //setting userid during authenticaion here.
            Result = Task.FromResult(
                AuthenticateResult.Success(new AuthenticationTicket(Principal, AuthSchemeName)));
        }
        catch
        {
            Result = Failure;
        }

        // refresh token goes here
        return await Result;
    }

我的集线器代码

public class DashboardHub : Hub
{
    private readonly Scope ThisScope;

    public DashboardHub(Scope scope)
    {
        ThisScope = scope; //scope.UserId is coming as Guid.Default which means that my change in authentication is not coming here.
    }
    
    public override Task OnConnectedAsync()
    {
        //ThisScope.UserId // will map it to Context.connectionId but its coming as Guid.Default
        return base.OnConnectedAsync();
    }
}

我的启动

// Here I add the scoped object where UserID is initially null but set during authentication.
services.AddScoped (sp => new Scope (TheConfig, logger, Clock));

I'm trying to authenticate my client by resolving sessionId to userId and set it in a scoped object. The code is able to authenticate and I'm setting the userid to the scoped object, but when I try to access this scoped object from Hub using DI, I'm not getting the scoped object rather a new object.

This method of authenticating is working for APIs.

My authenticator code

protected Scope Scope; // this is a custom class that stores userId along with some other params.

    public AuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock,
        Scope Scope)
        : base(options, logger, encoder, clock)
    {
        this.Scope = Scope;
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        Task<AuthenticateResult> Result = null;
        Task<AuthenticateResult> Failure = Task.FromResult(AuthenticateResult.Fail("not authorized"));

        try
        {
            var session = await GetSessionDetails(input);

            if (session == null)
            {
                return await Failure;
            }

            string Name = session.UserId;

            Scope.UserId = new Guid(session.UserId); //setting userid during authenticaion here.
            Result = Task.FromResult(
                AuthenticateResult.Success(new AuthenticationTicket(Principal, AuthSchemeName)));
        }
        catch
        {
            Result = Failure;
        }

        // refresh token goes here
        return await Result;
    }

My hub code

public class DashboardHub : Hub
{
    private readonly Scope ThisScope;

    public DashboardHub(Scope scope)
    {
        ThisScope = scope; //scope.UserId is coming as Guid.Default which means that my change in authentication is not coming here.
    }
    
    public override Task OnConnectedAsync()
    {
        //ThisScope.UserId // will map it to Context.connectionId but its coming as Guid.Default
        return base.OnConnectedAsync();
    }
}

My startup

// Here I add the scoped object where UserID is initially null but set during authentication.
services.AddScoped (sp => new Scope (TheConfig, logger, Clock));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦醒灬来后我 2025-01-24 03:11:26

这里有 2 个独立的作用域:

  • 请求作用域
  • 集线器调用作用域

它们是不同的,您的请求作用域服务是注入到集线器中的不同实例(在 DI 回调中放置一个断点,然后查看新获得的作用域对象)在构建集线器之前创建)。

在这种特殊情况下,您应该只使用声明主体,该主体通过 HubCallerContext.User 流向集线器;

There are 2 independent scopes at play here:

  • The request scope
  • The hub invocation scope

They are different and your request scoped services are different instances that what gets injected into the hub (put a break point in the DI callback and see the scope object get newly created before the hub is constructed).

In this particular case, you should just use the claims principal, that flows to the hub via the HubCallerContext.User;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文