- 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)
-
0
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.
-
0
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.
-
0
hi
Can you share your external login code and provide a test Microsoft account? liming.ma@volosoft.com
-
0
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); } }
-
0
hi @michael.sudnik
Can you share the
ClientId
andClientSecret
with me? so that I can test it locally.liming.ma@volosoft.com
-
0
hi
I received the mail, I will check, thank you
-
0
hi
I create a
mvc
project using4.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
-
0
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.
-
0
hi
It seems there is a problem with mongodb, I will check it. Thank you
-
0
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); } } }