Open Closed

CurrentUser.Id is null connecting to AbpHub #3499


0
Leonardo.Willrich created
  • ABP Framework version: v5.3
  • UI type: Blazor
  • DB provider: EF Core

Hi,

I have a third-party application that is using an access token to access the Web API method. It is working well so far. But, I need to send some real-time notifications to this application from my server and I'm using SignalR to do it. The problem is that the CurrentUser is null or has an invalid value. How to get the CurrentUser instance valid in the AbpHub implementation class? What parameters I should send when connecting to the hub?


7 Answer(s)
  • 0
    maliming created
    Support Team

    hi

    I need to send some real-time notifications to this application from my server and I'm using SignalR to do it.

    Please share some code of your hub.

  • 0
    Leonardo.Willrich created

    My hub is very simple, here is the code:

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.SignalR;
    using Microsoft.Extensions.Logging;
    using TVD_Holdings_Ltd.SBC.SignalRHub;
    using TVD_Holdings_Ltd.SBC.UIEventNotifications;
    using Volo.Abp.AspNetCore.SignalR;
    
    namespace TVD_Holdings_Ltd.SBC.UsersPresence
    {
        [HubRoute("/sbcUserPresence")]
        public class UsersPresenceSignalRHub : AbpHub
        {
            private readonly ILogger<UsersPresenceSignalRHub> _logger;
            private readonly IUserPresenceAppService _userPresenceAppService;
            internal static ConcurrentDictionary<string, Guid> Users = new ConcurrentDictionary<string, Guid>();
    
            public UsersPresenceSignalRHub(ILogger<UsersPresenceSignalRHub> logger, IUserPresenceAppService userPresenceAppService)
            {
                _logger = logger;
                _userPresenceAppService = userPresenceAppService;
            }
    
            public override async Task OnConnectedAsync()
            {
                _logger.LogDebug("UsersPresenceSignalRHub.OnConnectedAsync => CurrentUser.Id: {0}", CurrentUser.Id);
                if (CurrentUser != null && CurrentUser.Id.HasValue && CurrentTenant.Id.HasValue)
                {
                    await Groups.AddToGroupAsync(Context.ConnectionId, CurrentTenant.Id.GetValueOrDefault().ToString());
    
                    Users.TryAdd(Context.ConnectionId, CurrentUser.Id.GetValueOrDefault());
    
                    if (Users.Count(x => x.Value == CurrentUser.Id.GetValueOrDefault()) == 1)
                    {
                        _logger.LogDebug("UsersPresenceSignalRHub.OnConnectedAsync => Setting CurrentUser.Id: {0} as LoggedIn", CurrentUser.Id);
                        await _userPresenceAppService.SetUserLoggedIn();
                    }
                }
            }
    
            public override async Task OnDisconnectedAsync(Exception exception)
            {
                _logger.LogDebug("UsersPresenceSignalRHub.OnDisconnectedAsync => CurrentUser.Id: {0}", CurrentUser.Id);
                if (CurrentUser != null && CurrentUser.Id.HasValue && CurrentTenant.Id.HasValue)
                {
                    await Groups.RemoveFromGroupAsync(Context.ConnectionId, CurrentTenant.Id.GetValueOrDefault().ToString());
    
                    Users.TryRemove(Context.ConnectionId, out Guid userId);
                    if (Users.Count(x => x.Value == CurrentUser.Id.GetValueOrDefault()) == 0)
                    {
                        _logger.LogDebug("UsersPresenceSignalRHub.OnDisconnectedAsync => Setting CurrentUser.Id: {0} as LoggedOut", CurrentUser.Id);
                        await _userPresenceAppService.SetUserLoggedOut();
                    }
                }
            }
        }
    }
    
    

    Here is how the Client (Blazor WASM app) is connecting:

    presenceHub = new HubConnectionBuilder()
                    .WithUrl(baseUrl + "/sbcUserPresence")
                    .WithAutomaticReconnect(new SignalRRetryPolicy())
                    .Build()
                    .AssignConnectionEvents("User Presence");
                await presenceHub.StartAsync();
    

    I've tried to send the Token as well, but, it didn't changed:

    presenceHub = new HubConnectionBuilder()
                    .WithUrl(baseUrl + "/sbcUserPresence", options =>
                    {
                        options.AccessTokenProvider = GetAccessToken;
                    })
                    .WithAutomaticReconnect(new SignalRRetryPolicy())
                    .Build()
                    .AssignConnectionEvents("User Presence");
                await presenceHub.StartAsync();
    
  • 0
    maliming created
    Support Team

    hi

    What's the GetAccessToken method?

  • 0
    Leonardo.Willrich created

    It will return the current Token.

    public async Task<string> GetAccessToken()
            {
                _logger.LogDebug("AccessTokenManager.GetAccessToken - Starting...");
                await CheckAccessToken();
                if (_currentAccessToken == null || string.IsNullOrEmpty(_currentAccessToken.AccessToken))
                {
                    _logger.LogDebug("AccessTokenManager.GetAccessToken - Redirecting to Login page");
                    _navigationManager.NavigateTo("account/login");
                }
                _logger.LogDebug("AccessTokenManager.GetAccessToken - Completed");
                return _currentAccessToken?.AccessToken;
            }
    

    The _currentAccessToken was requested during the login and stored.

  • 0
    maliming created
    Support Team

    hi

    Can you check the User of Hub? see how many claims it has.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.signalr.hubcallercontext.user?view=aspnetcore-6.0

  • 0
    Leonardo.Willrich created

    Hi Maliming,

    I have cleared all site date for both applications (ABP.IO and third-party sites) and it seems to be working now.

    Here is the Context.User:

  • 0
    maliming created
    Support Team

    hi

    There is a HubFilter that will change current Principal.

    https://github.com/abpframework/abp/blob/f87e82c85ef07f0220dfaed1374858b33f4df164/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/AbpAspNetCoreSignalRModule.cs#L41 https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.AspNetCore.SignalR/Volo/Abp/AspNetCore/SignalR/Authentication/AbpAuthenticationHubFilter.cs#L20