Open Closed

How to connect a google login after account creation #5655


User avatar
0
william@iwell.nl created
  • ABP Framework version: v5.2
  • UI Type: Angular
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): Auth Server Separated (for Angular)

Hi ABP team,

i have a question about account creation. We would like to create account for new employees and prepare that before they start their onboarding. But this process is a bit cumbersome at the moment.

Two requirements:

  1. using google authentication is preferred, to avoid multiple accounts and credentials and different MFA steps
  2. account creation should not be allowed (otherwise random users can create accounts)

What we do now to create an account with google authentication:

  1. sit together with the new employee
  2. admin enables the self registration
  3. new user goes to login page and clicks the login with google button
  4. a register user screen appears and the account is created with the email of the google account. A blank screen appears (no permissions)
  5. admin adds permissions
  6. new user still sees a blank screen
  7. new user removes cookies and then the page and data becomes visible
  8. admin disables the self registration

We would like to improve this proces. Can you point us in a direction how to do this? Are we encountering a (known) bug or desired (to be build) feature of the framework or should we change our implementation?

Thanks a lot!


6 Answer(s)
  • User Avatar
    0
    Anjali_Musmade created
    Support Team Support Team Member

    Hi,

    Step 1 Disable Self registeration

    Step 2

    Create a role

    if you don't want to manually create a role you can use dataseeder to seed the role data make sure to mark the role as default so newly created user will have that role automatically https://docs.abp.io/en/abp/latest/Data-Seeding

    step 3 : create a Register.cshtml in AuthServer Project

    Step 4: Inside register.cshtm place this code

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using System.Linq;
    using System.Security.Claims;
    using System.Threading.Tasks;
    using Volo.Abp;
    using Volo.Abp.Account;
    using Volo.Abp.Account.Public.Web.Pages.Account;
    using Volo.Abp.Account.Settings;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Identity;
    using Volo.Abp.Identity.Settings;
    using Volo.Abp.Settings;
    
    namespace Acme.BookStore.Pages.Account
    {
        [ExposeServices(typeof(RegisterModel))]
        [Dependency(ReplaceServices = true)]
        public class AppRegisterModel : RegisterModel
        {
            public override async Task<IActionResult> OnGetAsync()
            {
                if (IsExternalLogin)
                {
                    await TrySetEmailAsync();
                    return await OnPostExternalInternalAsync();
                }else
                {
                    return await base.OnGetAsync();
                }
            }
    
            private async Task TrySetEmailAsync()
            {
                if (IsExternalLogin)
                {
                    var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
                    if (externalLoginInfo == null)
                    {
                        return;
                    }
    
                    if (!externalLoginInfo.Principal.Identities.Any())
                    {
                        return;
                    }
    
                    var identity = externalLoginInfo.Principal.Identities.First();
                    var emailClaim = identity.FindFirst(ClaimTypes.Email);
    
                    if (emailClaim == null)
                    {
                        return;
                    }
    
                    Input = new PostInput { EmailAddress = emailClaim.Value };
                }
            }
    
    
            public virtual async Task<IActionResult> OnPostExternalInternalAsync()
            {
                try
                {
                    await SetUseCaptchaAsync();
    
                    IdentityUser user;
                    if (IsExternalLogin)
                    {
                        var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();
                        if (externalLoginInfo == null)
                        {
                            Logger.LogWarning("External login info is not available");
                            return RedirectToPage("./Login");
                        }
    
                        user = await RegisterExternalUserAsync(externalLoginInfo, Input.EmailAddress);
                    }
                    else
                    {
                        var localLoginResult = await CheckLocalLoginAsync();
                        if (localLoginResult != null)
                        {
                            LocalLoginDisabled = true;
                            return localLoginResult;
                        }
    
                        user = await RegisterLocalUserAsync();
                    }
    
                    if (await SettingProvider.IsTrueAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail) && !user.EmailConfirmed ||
                        await SettingProvider.IsTrueAsync(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber) && !user.PhoneNumberConfirmed)
                    {
                        await StoreConfirmUser(user);
    
                        return RedirectToPage("./ConfirmUser", new
                        {
                            returnUrl = ReturnUrl,
                            returnUrlHash = ReturnUrlHash
                        });
                    }
    
                    await SignInManager.SignInAsync(user, isPersistent: true);
    
                    return Redirect(ReturnUrl ?? "/"); //TODO: How to ensure safety? IdentityServer requires it however it should be checked somehow!
                }
                catch (BusinessException e)
                {
                    Alerts.Danger(GetLocalizeExceptionMessage(e));
                    return Page();
                }
            }
        }
    }
    
    
    

    Now whenever there will be external login registeration will skip the CheckSelfRegistrationAsync check

  • User Avatar
    0
    william@iwell.nl created

    Hi Anjali,

    thanks for the quick response. Using a default role helps, newly created users will see something. This resolves the 'remove cookies' step.

    However, I'm still figuring out how to bypass the enable self registration step. We use the ABP commercial package which seem to handle all user management and registration. I could not find the pages/account folder to put the register.cshtm file in. Is there a way to modify this behaviour?

    Another question with regards to the ABP commercial package: does it contain functionality to connect a google login after account creation?

    Thank you!

  • User Avatar
    0
    Anjali_Musmade created
    Support Team Support Team Member

    Hi

    You have to manually create The folder and also create register.cshtml in Identity Server Web application

    and past the code which i have sent you in previous reply

    does it contain functionality to connect a google login after account creation? can you explain it with the scenario i am not able understand.

    you have to only register once after registration the login provider details get stored in these two tables along with the user created

    select * from [dbo].[AbpUserLogins]
    select * from [dbo].[AbpUserTokens]
    

    please explain with a scenario then will be able to provide you with more details

  • User Avatar
    0
    Anjali_Musmade created
    Support Team Support Team Member

    Hello william@iwell.nl,

    Does the solution worked for you given in the previous reply or help us understand the scenario ?

    Please do let us know so that we can assist you better.

    Thank You, Anjali

  • User Avatar
    0
    william@iwell.nl created

    Hi Anjali,

    does it contain functionality to connect a google login after account creation? can you explain it with the scenario i am not able understand.

    for example when we create user accounts, it would be convenient to have the following steps:

    1. as admin you create a user and set it's roles and organizational units
    2. as user you get an email, activate your account and login
    3. as user you want to use 2FA via google, and want to connect that to your account. So you can use that for future logins.

    Step 3 is, as far as I know, not possible at the moment? Note: we use the commercial packages.

  • User Avatar
    0
    Anjali_Musmade created
    Support Team Support Team Member

    Hi

    2FA is provided by abp commercial you just need tp enable it from the account settings https://docs.abp.io/en/commercial/latest/modules/identity/two-factor-authentication

    if you want to enable 2FA with Google Authenticator please see here https://docs.microsoft.com/en-us/aspnet/core/security/authentication/mfa?view=aspnetcore-6.0

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11