diff --git a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
index 8a5b54ecf1..9f10b7aa1d 100644
--- a/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
+++ b/modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Identity;
+using Volo.Abp.Validation;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
using UserLoginInfo = Volo.Abp.Account.Web.Areas.Account.Controllers.Models.UserLoginInfo;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
@@ -33,6 +34,8 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
{
ValidateLoginInfo(login);
+ await ReplaceEmailToUsernameOfInputIfNeeds(login);
+
return GetAbpLoginResult(await _signInManager.PasswordSignInAsync(
login.UserNameOrEmailAddress,
login.Password,
@@ -56,6 +59,28 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
return GetAbpLoginResult(await _signInManager.CheckPasswordSignInAsync(identityUser, login.Password, true));
}
+ protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds(UserLoginInfo login)
+ {
+ if (!ValidationHandler.IsValidEmailAddress(login.UserNameOrEmailAddress))
+ {
+ return;
+ }
+
+ var userByUsername = await _userManager.FindByNameAsync(login.UserNameOrEmailAddress);
+ if (userByUsername != null)
+ {
+ return;
+ }
+
+ var userByEmail = await _userManager.FindByEmailAsync(login.UserNameOrEmailAddress);
+ if (userByEmail == null)
+ {
+ return;
+ }
+
+ login.UserNameOrEmailAddress = userByEmail.UserName;
+ }
+
private static AbpLoginResult GetAbpLoginResult(SignInResult result)
{
if (result.IsLockedOut)
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj
index 25b1c9c888..91ff89e7aa 100644
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj
+++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj
@@ -19,6 +19,7 @@
+
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
index 7ddc619cfa..dbda3dd9aa 100644
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
+++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
@@ -7,6 +7,7 @@ using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.Modularity;
using Volo.Abp.Security;
+using Volo.Abp.Validation;
namespace Volo.Abp.IdentityServer
{
@@ -15,7 +16,8 @@ namespace Volo.Abp.IdentityServer
typeof(AbpAutoMapperModule),
typeof(AbpIdentityDomainModule),
typeof(AbpSecurityModule),
- typeof(AbpCachingModule)
+ typeof(AbpCachingModule),
+ typeof(AbpValidationModule)
)]
public class AbpIdentityServerDomainModule : AbpModule
{
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs
index eff9f4b0dc..f427d9edf1 100644
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs
+++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpResourceOwnerPasswordValidator.cs
@@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Volo.Abp.Security.Claims;
using Volo.Abp.Uow;
+using Volo.Abp.Validation;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.IdentityServer.AspNetIdentity
@@ -42,6 +43,8 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
[UnitOfWork]
public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
+ await ReplaceEmailToUsernameOfInputIfNeeds(context);
+
var user = await _userManager.FindByNameAsync(context.UserName);
if (user != null)
{
@@ -90,6 +93,28 @@ namespace Volo.Abp.IdentityServer.AspNetIdentity
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
}
+ protected virtual async Task ReplaceEmailToUsernameOfInputIfNeeds(ResourceOwnerPasswordValidationContext context)
+ {
+ if (!ValidationHandler.IsValidEmailAddress(context.UserName))
+ {
+ return;
+ }
+
+ var userByUsername = await _userManager.FindByNameAsync(context.UserName);
+ if (userByUsername != null)
+ {
+ return;
+ }
+
+ var userByEmail = await _userManager.FindByEmailAsync(context.UserName);
+ if (userByEmail == null)
+ {
+ return;
+ }
+
+ context.UserName = userByEmail.UserName;
+ }
+
protected virtual Task AddCustomClaimsAsync(List customClaims, IdentityUser user, ResourceOwnerPasswordValidationContext context)
{
if (user.TenantId.HasValue)