Browse Source

Add IExternalLoginProviderWithPassword

pull/12712/head
liangshiwei 4 years ago
parent
commit
7486582023
  1. 20
      modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs
  2. 45
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs
  3. 8
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs
  4. 26
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs
  5. 5
      modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs

20
modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs

@ -49,21 +49,27 @@ public class AbpSignInManager : SignInManager<IdentityUser>
var user = await UserManager.FindByNameAsync(userName);
if (user == null)
{
user = externalLoginProvider.CanObtainUserInfoWithoutPassword
? await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name)
: await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name, password);
if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() &&
externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword)
{
user = await externalLoginProviderWithPassword.CreateUserAsync(userName, externalLoginProviderInfo.Name, password);
}
else
{
user = await externalLoginProvider.CreateUserAsync(userName, externalLoginProviderInfo.Name);
}
}
else
{
if (externalLoginProvider.CanObtainUserInfoWithoutPassword)
if (!externalLoginProvider.CanObtainUserInfoWithoutPassword() &&
externalLoginProvider is IExternalLoginProviderWithPassword externalLoginProviderWithPassword)
{
await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name);
await externalLoginProviderWithPassword.UpdateUserAsync(user, externalLoginProviderInfo.Name, password);
}
else
{
await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name, password);
await externalLoginProvider.UpdateUserAsync(user, externalLoginProviderInfo.Name);
}
}
return await SignInOrTwoFactorAsync(user, isPersistent);

45
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/ExternalLoginProviderBase.cs

@ -9,16 +9,13 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity;
public abstract class ExternalLoginProviderBase : IExternalLoginProvider
public abstract class ExternalLoginProviderBase : IExternalLoginProvider, IExternalLoginProviderWithPassword
{
protected IGuidGenerator GuidGenerator { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IdentityUserManager UserManager { get; }
protected IIdentityUserRepository IdentityUserRepository { get; }
protected IOptions<IdentityOptions> IdentityOptions { get; }
public bool CanObtainUserInfoWithoutPassword { get; set; }
protected ExternalLoginProviderBase(
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
@ -31,19 +28,32 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider
UserManager = userManager;
IdentityUserRepository = identityUserRepository;
IdentityOptions = identityOptions;
CanObtainUserInfoWithoutPassword = true;
}
public abstract Task<bool> TryAuthenticateAsync(string userName, string plainPassword);
public abstract Task<bool> IsEnabledAsync();
public virtual async Task<IdentityUser> CreateUserAsync(string userName, string providerName, string plainPassword = null)
public virtual async Task<IdentityUser> CreateUserAsync(string userName, string providerName)
{
await IdentityOptions.SetAsync();
var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(userName) : await GetUserInfoAsync(userName, plainPassword);
var externalUser = await GetUserInfoAsync(userName);
return await CreateUserAsync(externalUser, userName, providerName);
}
public virtual async Task<IdentityUser> CreateUserAsync(string userName, string providerName, string plainPassword)
{
await IdentityOptions.SetAsync();
var externalUser = await GetUserInfoAsync(userName, plainPassword);
return await CreateUserAsync(externalUser, userName, providerName);
}
protected virtual async Task<IdentityUser> CreateUserAsync(ExternalLoginUserInfo externalUser, string userName, string providerName)
{
NormalizeExternalLoginUserInfo(externalUser, userName);
var user = new IdentityUser(
@ -82,17 +92,26 @@ public abstract class ExternalLoginProviderBase : IExternalLoginProvider
return user;
}
public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null)
public virtual async Task UpdateUserAsync(IdentityUser user, string providerName)
{
await IdentityOptions.SetAsync();
var externalUser = await GetUserInfoAsync(user);
if (!CanObtainUserInfoWithoutPassword)
{
Check.NotNullOrWhiteSpace(plainPassword, nameof(plainPassword));
}
await UpdateUserAsync(user, externalUser, providerName);
}
public virtual async Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword)
{
await IdentityOptions.SetAsync();
var externalUser = CanObtainUserInfoWithoutPassword ? await GetUserInfoAsync(user) : await GetUserInfoAsync(user, plainPassword);
var externalUser = await GetUserInfoAsync(user, plainPassword);
await UpdateUserAsync(user, externalUser, providerName);
}
protected virtual async Task UpdateUserAsync(IdentityUser user, ExternalLoginUserInfo externalUser ,string providerName)
{
NormalizeExternalLoginUserInfo(externalUser, user.UserName);
if (!externalUser.Name.IsNullOrWhiteSpace())

8
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProvider.cs

@ -4,7 +4,7 @@ namespace Volo.Abp.Identity;
public interface IExternalLoginProvider
{
bool CanObtainUserInfoWithoutPassword { get; set; }
bool CanObtainUserInfoWithoutPassword();
/// <summary>
/// Used to try authenticate a user by this source.
@ -20,9 +20,8 @@ public interface IExternalLoginProvider
/// </summary>
/// <param name="userName">User name</param>
/// <param name="providerName">The name of this provider</param>
/// <param name="plainPassword">Optional, plain password of the user</param>
/// <returns>Newly created user</returns>
Task<IdentityUser> CreateUserAsync(string userName, string providerName, string plainPassword = null);
Task<IdentityUser> CreateUserAsync(string userName, string providerName);
/// <summary>
/// This method is called after an existing user is authenticated by this source.
@ -30,8 +29,7 @@ public interface IExternalLoginProvider
/// </summary>
/// <param name="providerName">The name of this provider</param>
/// <param name="user">The user that can be updated</param>
/// <param name="plainPassword">Optional, plain password of the user</param>
Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword = null);
Task UpdateUserAsync(IdentityUser user, string providerName);
/// <summary>
/// Return a value indicating whether this source is enabled.

26
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IExternalLoginProviderWithPassword.cs

@ -0,0 +1,26 @@
using System.Threading.Tasks;
namespace Volo.Abp.Identity
{
public interface IExternalLoginProviderWithPassword
{
/// <summary>
/// This method is called when a user is authenticated by this source but the user does not exists yet.
/// So, the source should create the user and fill the properties.
/// </summary>
/// <param name="userName">User name</param>
/// <param name="providerName">The name of this provider</param>
/// <param name="plainPassword">The plain password of the user</param>
/// <returns>Newly created user</returns>
Task<IdentityUser> CreateUserAsync(string userName, string providerName, string plainPassword);
/// <summary>
/// This method is called after an existing user is authenticated by this source.
/// It can be used to update some properties of the user by the source.
/// </summary>
/// <param name="providerName">The name of this provider</param>
/// <param name="user">The user that can be updated</param>
/// <param name="plainPassword">The plain password of the user</param>
Task UpdateUserAsync(IdentityUser user, string providerName, string plainPassword);
}
}

5
modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/FakeExternalLoginProvider.cs

@ -28,6 +28,11 @@ public class FakeExternalLoginProvider : ExternalLoginProviderBase, ITransientDe
}
public override bool CanObtainUserInfoWithoutPassword()
{
return true;
}
public override Task<bool> TryAuthenticateAsync(string userName, string plainPassword)
{
return Task.FromResult(

Loading…
Cancel
Save