Open Closed

Trouble Auto Registering Users #7186


User avatar
0
brauerj@gc.adventist.org created
  • ABP Framework version: v8.1.2
  • UI Type: Blazor Server
  • Database System: EF Core (SQL Server)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no

There seems to be an issue with the logic in modules\account\src\Volo.Abp.Account.Web\Pages\Account\Register.cshtml.cs

On line 71 I see IsExternalLoginOnly but there seems to be NO way to get to this! The function CheckSelfRegistrationAsync returns TRUE if ANY external login exists (line 206) which would obviously make it empossible for line 71 to EVER run and thus for OnPostExternalLogin to ever run. Am I missing something? I disabled both Abp.Account.EnableLocalLogin and Abp.Account.IsSelfRegistrationEnabled but then was surprised to still see a registration screen. What am I missing? I see your response to https://support.abp.io/QA/Questions/6843/External-Provider-login-is-able-to-register-a-user-even-if-self-register-setting-is-disabled but I still think there might be a bug here? Shouldn't line 71 be able to run somehow? Shouldn't there just be a standard place to autoregister a user.

This used to be done easily by a function CreateExternalUserAsync(ExternalLoginInfo info) on LoginModel but that seemed to go away. What is the replacement to that function?

Also, previously I had made the decision to use email address for username for all users but I see this is NOT the default approach ABP takes. Is there a "standard" way to change this? Is overriding UserManager.GetUserNameFromEmailAsync() to just return the email address a bad idea?

Thanks,

Jonathan


7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I disabled both Abp.Account.EnableLocalLogin and Abp.Account.IsSelfRegistrationEnabled but then was surprised to still see a registration screen. What am I missing?

    The page will have a warning message. This is the default behavior.

    Can you explain what you expect from this case?

    This used to be done easily by a function CreateExternalUserAsync(ExternalLoginInfo info) on LoginModel but that seemed to go away. What is the replacement to that function?

    I think the new method is protected virtual async Task<IdentityUser> RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string userName, string emailAddress)

    I had made the decision to use email address for username for all users

    You can customize the login/register page to hide the username input and use email everywhere.

    Replace Input.UserName with Input.EmailAddress

  • User Avatar
    0
    brauerj@gc.adventist.org created

    The page will have a warning message. This is the default behavior.

    I believe this is the default behavior when there are no External Providers but if there are one or more external login providers I believe CheckSelfRegistrationAsync will ALWAYS be true because of line 204:

     protected virtual async Task<bool> CheckSelfRegistrationAsync()
        {
            EnableLocalRegister = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin) &&
                                  await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled);
    
    204     if (IsExternalLogin)
            {
                return true;
            }
    
            if (!EnableLocalRegister)
            {
                return false;
            }
    
            return true;
        }
    

    Thus it will show the form WITHOUT the SelfRegistrationDisabledMessage warning and never run OnPostExternalLogin. But anyways I'm hoping I don't need to concern myself with this page as I don't really want them to see a "registration" page, but to auto register in the background (like I used to have it).

    IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;

    Which equates to true in my case but line 69 never runs from what I can see:

        public virtual async Task<IActionResult> OnGetAsync()
        {
            ExternalProviders = await GetExternalProviders();
    
            if (!await CheckSelfRegistrationAsync())
            {
    70          if (IsExternalLoginOnly)
                {
                    return await OnPostExternalLogin(ExternalLoginScheme);
                }
    
                Alerts.Warning(L["SelfRegistrationDisabledMessage"]);
            }
    
            await TrySetEmailAsync();
    
            return Page();
        }
    

    I think the new method is protected virtual async Task<IdentityUser> RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string userName, string emailAddress)

    RegisterExternalUserAsync only seems to run when the Register page is filled out and submitted? I want to avoid that and have them registered in the background without the users involvement. Overriding CreateExternalUserAsync(ExternalLoginInfo info) (referenced here) allowed me to do this. It looks like this was available recently?

    Main point, how can I register someone automatically based on the claims received from an external provider? Previously I just overrode CreateExternalUserAsync on LoginModel.

    Thanks in advance.

  • User Avatar
    0
    brauerj@gc.adventist.org created

    This would be a GREAT solution but no longer seems to be available.

    I do see I can still override OnGetExternalLoginCallbackAsync for LoginModel which is a bit more messy but seems like it should work.

    Perhaps a true/false "enable external user auto creation" setting which defaults to running a function which could be overridden would make the most sense to me.

    Do you have a sample on how you'd best see that done? The Authentication-Customization sample in abp-samples still seems to override CreateExternalUserAsync.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Main point, how can I register someone automatically based on the claims received from an external provider? Previously I just overrode CreateExternalUserAsync on LoginModel.

    You can override the Task<IActionResult> OnGetAsync() method

    if IsExternalLogin is true, then get user info by var externalLoginInfo = await SignInManager.GetExternalLoginInfoAsync();

    Do your register logic in the OnGetAsync by copy code from OnPostAsync method.

  • User Avatar
    0
    roberto.fiocchi created

    I also had a similar problem in the scenario where I need to have the ability to log in locally and the ability to login via Active Directory active, but a user cannot "self" register. Only an administrator can create accounts and without a created account a user cannot log in.

    See my post https://support.abp.io/QA/Questions/6843/External-Provider-login-is-able-to-register-a-user-even-if-self-register-setting-is-disabled

    So I also had to override the methods, but I think the correct solution is to have a flag that enables/disables the creation of a local user (self registration) and a flag that enables/disables registration from External Provider (automatic external registration)

    Is it possible to have this feature?

    Thanks

  • User Avatar
    0
    brauerj@gc.adventist.org created

    I agree. It seems clear to me that a setting and pattern or two are missing somewhere to make this much cleaner for the various desired outcomes we each are working towards.

  • User Avatar
    1
    maliming created
    Support Team Fullstack Developer

    hi all

    We will create an issue to track this internally. You can override the code as a temporary solution.

    Your question credit has been refunded.

    Thanks.

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