Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

GetUserByIdAsync can't find user Id 1 when impersonating a User after logging in as (host) 'admin'. #8064


User avatar
0
TimMackey created
ERROR 2019-11-21 16:11:48,693 [35   ] Mvc.ExceptionHandling.AbpExceptionFilter - There is no user with id: 1
Abp.AbpException: There is no user with id: 1
   at Abp.Authorization.Users.AbpUserManager`2.GetUserByIdAsync(Int64 userId) in D:\Github\aspnetboilerplate\src\Abp.ZeroCore\Authorization\Users\AbpUserManager.cs:line 340

 // (more proprietary stack data omitted)

...occurs when attempting to get the impersonator User Id (Id = 1).

var susr = AbpSession.ImpersonatorUserId > 0
         ? AbpSession.ImpersonatorUserId
         : AbpSession.UserId;

var rler = await _userManager.GetUserByIdAsync(susr.Value);
var rlerRoles = await _userManager.GetRolesAsync(rler);

The user with Id = 1 is created in HostRoleAndUserCreator.cs, and exists in the dbo.AbpUsers table.

        private void CreateHostRoleAndUsers()
        {
                // (omitted code)
                
                //admin user for host

                var adminUserForHost = _context.Users.IgnoreQueryFilters().FirstOrDefault(u => u.TenantId == null && u.UserName == AbpUserBase.AdminUserName);
                if (adminUserForHost == null)
                {
                    var user = new User
                    {
                        TenantId = null,
                        UserName = AbpUserBase.AdminUserName,
                        Name = "admin",
                        Surname = "admin",
                        EmailAddress = "[email protected]",
                        IsEmailConfirmed = true,
                        ShouldChangePasswordOnNextLogin = false,
                        IsActive = true,
                        Password = "AM4OLBpptxBYmM79lGOX9egzZk3vIQU3d/gFCJzaBjAPXzYIK3tQ2N7X4fcrHtElTw==" //123qwe
                    };

                    user.SetNormalizedNames();

                    adminUserForHost = _context.Users.Add(user).Entity;
                    _context.SaveChanges();
                    
                     // (omitted code)
         }

When impersonating a User after logging in as tenant admin the code does not throw an exception. When impersonating a User after logging in as host atmin the code throws an exception.


5 Answer(s)
  • User Avatar
    0
    TimMackey created

    When impersonating a User after logging in as host admin, the Exception identified at the start of this post ("There is no user with id: 1") is thrown when _userManager.GetUserByIdAsync(currentUser.Value); is called.

    Specific steps:

    1. login as host admin
    2. navigate to 'Tenants'
    3. Under 'Actions', select 'Login as this tenant'
    4. Select a non-admin tenant to impersonate. The impersonated User's id is 4, however currentUser.Value = 1, which is the host admin Id.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @timmackey

    Does this happen during development tiem or production ? If it is production, do you use sbudomain name as tenancy name ?

    Thanks,

  • User Avatar
    0
    TimMackey created

    This happens during development. The only way to obtain the screenshot above is with a Debug build. The tenancy name is NOT being used as a subdomain, although I would like to be able to do that in the future.

  • User Avatar
    0
    maliming created
    Support Team

    hi timmackey

    You can try the SetTenantId method to switch the tenant of the current unit of work.

    Because the host user cannot be queried under the tenant

       using (_unitOfWorkManager.Current.SetTenantId(tenantId))
        {
            var susr = AbpSession.ImpersonatorUserId > 0
                     ? AbpSession.ImpersonatorUserId
                     : AbpSession.UserId;
    
            var rler = await _userManager.GetUserByIdAsync(susr.Value);
            var rlerRoles = await _userManager.GetRolesAsync(rler);
        }
    
  • User Avatar
    0
    TimMackey created

    The solution I settled on was to test if (AbpSession.ImpersonatorUserId == 1), then don't call _userManager.GetUserByIdAsync, since by definition if the UserId is 1, then I know who the user is - the host admin.