Open Closed

Unable to login with Microsoft external provider after email registration because email registration process is repeated #543


User avatar
0
michael.sudnik created
  • ABP Framework version: 3.3.1
  • UI type: MVC
  • Tiered (MVC) or Identity Server Seperated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:

After enabling the Microsoft external provider for my organisation, the first time click the Microsoft button on the login page and register my email address, I am then logged into the system correctly.

However, after logging out and trying to log back in again using the Microsoft button, it asks me to register my email address again - which it should not be doing. Obviously, I am unable to register again as both my username and email address are already in the system (and clicking the "Already registered? Login" just takes me to the start again).

I think that the problem might be that my username for my organisation is actually different to my email address. Email format: joe.blogs@myorganisation.com Microsoft username format: jblogs@myorganisation.com

What I can see is that after registration, the system is incorrectly recording my username to actually be my email address (e.g. joe.blogs@myorganisation.com when it should probably be jblogs@myorganisation.com), which might be causing the problem.

Are you able to point me in the right direction to try and debug this problem? Are there any hooks in the code that would allow me to try and investigate this?


10 Answer(s)
  • User Avatar
    0
    michael.sudnik created

    Maybe the problem is here and the AbpClaimTypes.Email is not available?

    https://github.com/abpframework/abp/blob/de7d480af49b5292716a3d130c4602da202388c2/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs#L226

    But, the "Register Email" page does seem to populate it ok.

  • User Avatar
    0
    michael.sudnik created

    I still have not figured out what is going on. I have tried implementing a custom AbpSignInManager and can see that the ExternalLoginSignInAsync method result has all properties set to false (Failed). The method is also not hitting the PreSignInCheck, which implies that it is failing in the UserManager.FindByLoginAsync(loginProvider, providerKey) method. After investigating what this does, it is suspicious that the user in the database does not have any logins associated with it. I am using MongoDB and am wondering if the logins are not being persisted to the database. Also - the IsExternal property is set to false, which does not seem right. I will keep investigating until someone else can offer any help. Thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share your external login code and provide a test Microsoft account? liming.ma@volosoft.com

  • User Avatar
    0
    michael.sudnik created

    I have now created a brand new v4.0.0-rc3 version and made only a single modification to the code.

    .AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, "Company", options =>
                    {
                        options.AuthorizationEndpoint = "https://login.microsoftonline.com/[###MY TENENT ID###]/oauth2/v2.0/authorize";
                        options.TokenEndpoint = "https://login.microsoftonline.com/[##MY TENENT ID###]/oauth2/v2.0/token";
                    })
    

    The problem occurs when running locally, without publishing to azure.

    The inclusion of the following code, fixes the problem for some reason:

     [Dependency(ReplaceServices = true)]
        [ExposeServices(typeof(RegisterModel))]
        public class CustomRegisterModel : RegisterModel
        {
            protected override async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress)
            {
                var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
    
                (await UserManager.CreateAsync(user)).CheckErrors();
                (await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
    
                var userLoginAlreadyExists = user.Logins.Any(x =>
                    x.TenantId == user.TenantId &&
                    x.LoginProvider == externalLoginInfo.LoginProvider &&
                    x.ProviderKey == externalLoginInfo.ProviderKey);
    
                if (!userLoginAlreadyExists)
                {
                    (await UserManager.AddLoginAsync(user, new UserLoginInfo(
                        externalLoginInfo.LoginProvider,
                        externalLoginInfo.ProviderKey,
                        externalLoginInfo.ProviderDisplayName
                    ))).CheckErrors();
                }
    
                await SignInManager.SignInAsync(user, isPersistent: true);
            }
        }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi @michael.sudnik

    Can you share the ClientId and ClientSecret with me? so that I can test it locally.

    liming.ma@volosoft.com

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I received the mail, I will check, thank you

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I create a mvc project using 4.0.0-rc.3, When I register with my email, it will automatically log in when I log in again.

    ! 4.0.0 has not yet released the official version, RC is for testing only.
    
    dotnet tool uninstall --global Volo.Abp.Cli && dotnet tool install --global Volo.Abp.Cli --version 4.0.0-rc.3
    abp new MyApp -t app-pro -u mvc --mobile none --database-provider ef --csf --preview
    

  • User Avatar
    0
    michael.sudnik created

    Hi,

    When i perform the same steps as you to create a new solution (using EF), I can confirm that it works and I can logout and log back in again repeatedly without any problems.

    However, when I create a new app using the MongoDB database provider, I then see the incorrect behaviour.

    abp new MyApp -t app-pro -u mvc --mobile none --database-provider mongodb --csf --preview
    

    Thanks for looking into it.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    It seems there is a problem with mongodb, I will check it. Thank you

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi @michael.sudnik

    The below code is the patch. I will fix this in 4.0.

    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Identity;
    using Volo.Abp.Account;
    using Volo.Abp.Account.Public.Web.Pages.Account;
    using Volo.Abp.DependencyInjection;
    using IdentityUser = Volo.Abp.Identity.IdentityUser;
    
    namespace MyApp.Web
    {
          [ExposeServices(typeof(MyRegisterModel), typeof(RegisterModel))]
          public class MyRegisterModel : RegisterModel
          {
                protected override async Task RegisterExternalUserAsync(ExternalLoginInfo externalLoginInfo, string emailAddress)
                {
                      var user = new IdentityUser(GuidGenerator.Create(), emailAddress, emailAddress, CurrentTenant.Id);
    
                      (await UserManager.CreateAsync(user)).CheckErrors();
                      (await UserManager.AddDefaultRolesAsync(user)).CheckErrors();
    
                      if (!user.EmailConfirmed)
                      {
                            await AccountAppService.SendEmailConfirmationTokenAsync(
                                  new SendEmailConfirmationTokenDto
                                  {
                                        AppName = "MVC",
                                        Email = emailAddress,
                                        ReturnUrl = ReturnUrl,
                                        ReturnUrlHash = ReturnUrlHash
                                  }
                            );
                      }
    
                      var userLoginAlreadyExists = user.Logins.Any(x =>
                            x.TenantId == user.TenantId &&
                            x.LoginProvider == externalLoginInfo.LoginProvider &&
                            x.ProviderKey == externalLoginInfo.ProviderKey);
    
                      if (!userLoginAlreadyExists)
                      {
                            user.AddLogin(new UserLoginInfo(
                                        externalLoginInfo.LoginProvider,
                                        externalLoginInfo.ProviderKey,
                                        externalLoginInfo.ProviderDisplayName
                                  )
                            );
    
                            (await UserManager.UpdateAsync(user)).CheckErrors();
                      }
    
                      await SignInManager.SignInAsync(user, isPersistent: true);
                }
          }
    }
    
    
Made with ❤️ on ABP v9.1.0-preview. Updated on December 12, 2024, 07:15