Base solution for your next web application
Open Closed

Social Login #1867


User avatar
0
amayorquin created

Hi,

I have a problem when I use social login to authenticate users (Using different database for each tenant), I can register the user without problems, but when I logout and try to login again, it redirects to the register page. I checked the code and there is a function that try to find possible tenants for that login, but the problem is that is searching in the host database and the user is registered in a tenant database.

I guess I have to pass the tenant name to make this work. Is there a reason you make this in that way? Or is an error?

Thanks in advance!


4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Tenants are stored in the host database, that's way host database is used for finding tenant. Can you share your code for this problem ? The code which finds tenancy name ?

  • User Avatar
    0
    amayorquin created

    Thanks for your reply,

    Actually I'm not change anything yet in code, I just downloaded the ABP and started to check and debug the code.

    When I try Login with an external account previously registered (Google), this method is called (tenancyName is empty):

    [UnitOfWork]
            public virtual async Task<ActionResult> ExternalLoginCallback(string returnUrl, string tenancyName = "")
            {
                var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
                if (loginInfo == null)
                {
                    return RedirectToAction("Login");
                }
    
                //Try to find tenancy name
                if (tenancyName.IsNullOrEmpty())
                {
                    var tenants = await FindPossibleTenantsOfUserAsync(loginInfo.Login);
                    switch (tenants.Count)
                    {
                        case 0:
                            return await RegisterView(loginInfo);
                        case 1:
                            tenancyName = tenants[0].TenancyName;
                            break;
                        default:
                            return View("TenantSelection", new TenantSelectionViewModel
                            {
                                Action = Url.Action("ExternalLoginCallback", "Account", new { returnUrl }),
                                Tenants = tenants.MapTo<List<TenantSelectionViewModel.TenantInfo>>()
                            });
                    }
                }
    
                var loginResult = await _logInManager.LoginAsync(loginInfo.Login, tenancyName);
    
                switch (loginResult.Result)
                {
                    case AbpLoginResultType.Success:
                        await SignInAsync(loginResult.User, loginResult.Identity, false);
    
                        if (string.IsNullOrWhiteSpace(returnUrl))
                        {
                            returnUrl = Url.Action("Index", "Home");
                        }
    
                        return Redirect(returnUrl);
                    case AbpLoginResultType.UnknownExternalLogin:
                        return await RegisterView(loginInfo, tenancyName);
                    default:
                        throw CreateExceptionForFailedLoginAttempt(loginResult.Result, loginInfo.Email ?? loginInfo.DefaultUserName, tenancyName);
                }
            }
    

    The method that is called to find the possible tenants is the following:

    [UnitOfWork]
            protected virtual async Task<List<Tenant>> FindPossibleTenantsOfUserAsync(UserLoginInfo login)
            {
                List<User> allUsers;
                using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
                {
                    allUsers = await _userManager.FindAllAsync(login);
                }
    
                return allUsers
                    .Where(u => u.TenantId != null)
                    .Select(u => AsyncHelper.RunSync(() => _tenantManager.FindByIdAsync(u.TenantId.Value)))
                    .ToList();
            }
    

    but like I said before, looks like is searching only in the host database

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Thanks, I remember now :). This is not an error, we did it on purpose. Otherwise we need to query all tenant databases to find matching users for that social login.

    If you are using different subdomain for each tenant, the you can find tenancyName according to current url before this line <a class="postlink" href="https://github.com/aspnetboilerplate/module-zero-template/blob/d0745669097e6876ae641682f56ffc6eb256d0c9/src/AbpCompanyName.AbpProjectName.WebSpaAngular/Controllers/AccountController.cs#L334">https://github.com/aspnetboilerplate/mo ... er.cs#L334</a>

    and use it as tenancyName. This might solve your problem.

  • User Avatar
    0
    amayorquin created

    Thank you very much. This is how I was thinking to solve it, but I had the doubt if you did this on purpose. Thanks again