Base solution for your next web application
Open Closed

Why not use aspsession for registering a new user? #403


User avatar
0
sylfree9999 created

Hi,

I have been trying to create a new user with a new tenantId like this:

var newUser= new User
                {
                    UserName = input.UserName,
                    Password = new PasswordHasher().HashPassword("test1@!"), 
                    TenantId = tenantId//This tenantId is not the default tenant, let's say it's 3 right now
                };
            
               (await _userManager.CreateAsync(newUser)).CheckErrors();
                await _unitOfWorkManager.Current.SaveChangesAsync(); // Then I used the sql profiler to see what is stored in db, surprisingly even I set the tenantId to 3, it still stored tenantId to 1(which is default value)

I have been searching why this happens. Some says that the tenantId has to be set on the userstore class. But I don't understand why.

So I try to find out how the CreateAsync works. And I have noticed that hikalkan once said in here :[https://github.com/aspnetboilerplate/module-zero/issues/40]): <span style="color:#FF0000">You should not use AbpSession while registering a new user. It gets user and tenant id from cookie and will be set after login of new registered user</span>. I don't quite get it. What's the difference between the aspsession and cookies?

And then I thought maybe I need to update the claim to get the corrent tenantId since the code gets the first default one. If I create the user when registering, adding the claim requires me to save the user first, which will again set the wrong tenantId. And this is the issue I was trying to resolve. This is a dead loop I think. Another scenario, if I logged in as a superuser with default tenantId(1), then I created a new tenant(3) and trying to add users under this tenant. This user creation operation will still get the wrong tenant since it also uses the claimed tenantId value. I'm quite lost here, what should I do to fix this? Or am I heading to the wrong direction?

public override async Task<IdentityResult> CreateAsync(TUser user)
        {
            var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress);
            if (!result.Succeeded)
            {
                return result;
            }

            if (AbpSession.TenantId.HasValue)
            {
                user.TenantId = AbpSession.TenantId.Value;
            }

            return await base.CreateAsync(user);
        }

  public int? TenantId
        {
            get
            {
                if (!_multiTenancy.IsEnabled)
                {
                    return DefaultTenantId;
                }

                var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;
                if (claimsPrincipal == null)
                {
                    return null;
                }

                var claim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == AbpClaimTypes.TenantId);
                if (claim == null || string.IsNullOrEmpty(claim.Value))
                {
                    return null;
                }
                
                return Convert.ToInt32(claim.Value);
            }
        }

1 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Short answer: Why don't you use the method in the template: <a class="postlink" href="https://github.com/aspnetboilerplate/module-zero-template/blob/master/src/AbpCompanyName.AbpProjectName.WebSpaAngular/Controllers/AccountController.cs#L169">https://github.com/aspnetboilerplate/mo ... er.cs#L169</a> It just works as expected.

    A bit more info:

    • Have you enabled multi-tenancy? If not, ABP always use TenantId = 1 (as default).
    • You can use filters to work the tenant you want. See the related doc: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Zero/User-Management#multi-tenancy">http://www.aspnetboilerplate.com/Pages/ ... ti-tenancy</a>