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 700d52b3a9..5bc347d84d 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
@@ -6,6 +6,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;
@@ -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 f642574118..d485c69016 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 00d5d1039a..60af80e1da 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
@@ -12,6 +12,7 @@ using Microsoft.Extensions.Logging;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Uow;
+using Volo.Abp.Validation;
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)