From 0ae62dcfe98dd73dcc476d18b30bdf2b19579853 Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 May 2022 14:55:58 +0800 Subject: [PATCH] Add CanObtainUserInfoWithoutPassword to IExternalLoginProvider --- .../Identity/AspNetCore/AbpSignInManager.cs | 14 +++++++-- .../Abp/Identity/ExternalLoginProviderBase.cs | 29 +++++++++++++++---- .../Abp/Identity/IExternalLoginProvider.cs | 8 +++-- .../AspNetCore/FakeExternalLoginProvider.cs | 5 ++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs index 313be4ae3f..946435e87c 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs @@ -49,11 +49,21 @@ public class AbpSignInManager : SignInManager var user = await UserManager.FindByNameAsync(userName); if (user == null) { - user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name); + user = externalLoginProvider.CanObtainUserInfoWithoutPassword + ? await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name) + : await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name, password); } else { - await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + if (externalLoginProvider.CanObtainUserInfoWithoutPassword) + { + await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name); + } + else + { + await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name, password); + } + } return await SignInOrTwoFactorAsync(user, isPersistent); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs index cfefad2a95..ba85576ace 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs @@ -16,6 +16,8 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider protected IdentityUserManager UserManager { get; } protected IIdentityUserRepository IdentityUserRepository { get; } protected IOptions IdentityOptions { get; } + + public bool CanObtainUserInfoWithoutPassword { get; set; } protected ExternalLoginProviderBase( IGuidGenerator guidGenerator, @@ -29,19 +31,21 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider UserManager = userManager; IdentityUserRepository = identityUserRepository; IdentityOptions = identityOptions; + CanObtainUserInfoWithoutPassword = true; } public abstract Task TryAuthenticateAsync(string userName, string plainPassword); - + public abstract Task IsEnabledAsync(); - public virtual async Task CreateUserAsync(string userName, string providerName) + public virtual async Task CreateUserAsync(string userName, string providerName, string plainPassword = null) { await IdentityOptions.SetAsync(); - var externalUser = await GetUserInfoAsync(userName); - NormalizeExternalLoginUserInfo(externalUser, userName); + var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(userName) : await GetUserInfoAsync(userName, plainPassword); + NormalizeExternalLoginUserInfo(externalUser, userName); + var user = new IdentityUser( GuidGenerator.Create(), userName, @@ -78,11 +82,17 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider return user; } - public virtual async Task UpdateUserAsync(IdentityUser user, string providerName) + public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null) { await IdentityOptions.SetAsync(); - var externalUser = await GetUserInfoAsync(user); + if (!CanObtainUserInfoWithoutPassword) + { + Check.NotNullOrWhiteSpace(plainPassword, nameof(plainPassword)); + } + + var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(user) : await GetUserInfoAsync(user, plainPassword); + NormalizeExternalLoginUserInfo(externalUser, user.UserName); if (!externalUser.Name.IsNullOrWhiteSpace()) @@ -147,10 +157,17 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider protected abstract Task GetUserInfoAsync(string userName); + protected abstract Task GetUserInfoAsync(string userName, string plainPassword); + protected virtual Task GetUserInfoAsync(IdentityUser user) { return GetUserInfoAsync(user.UserName); } + + protected virtual Task GetUserInfoAsync(IdentityUser user, string plainPassword) + { + return GetUserInfoAsync(user.UserName, plainPassword); + } private static void NormalizeExternalLoginUserInfo( ExternalLoginUserInfo externalUser, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs index 52d3895d13..7621c54de6 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs @@ -4,6 +4,8 @@ namespace Volo.Abp.Identity; public interface IExternalLoginProvider { + bool CanObtainUserInfoWithoutPassword { get; set; } + /// /// Used to try authenticate a user by this source. /// @@ -18,8 +20,9 @@ public interface IExternalLoginProvider /// /// User name /// The name of this provider + /// Optional, plain password of the user /// Newly created user - Task CreateUserAsync(string userName, string providerName); + Task CreateUserAsync(string userName, string providerName, string plainPassword = null); /// /// This method is called after an existing user is authenticated by this source. @@ -27,7 +30,8 @@ public interface IExternalLoginProvider /// /// The name of this provider /// The user that can be updated - Task UpdateUserAsync(IdentityUser user, string providerName); + /// Optional, plain password of the user + Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null); /// /// Return a value indicating whether this source is enabled. diff --git a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs index fbfc0e2ef6..038e8cde0c 100644 --- a/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs +++ b/modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs @@ -60,4 +60,9 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe } ); } + + protected override Task GetUserInfoAsync(string userName, string plainPassword) + { + return GetUserInfoAsync(userName); + } }