您可以扩展IResourceOwnerPasswordValidator 并覆盖ValidateAsync 方法
您可以通过用户名和代码或电话和代码来检查,而不是通过用户和密码进行检查。
检查下面的实现并将CheckPasswordSignInAsync替换为您的实现,如果成功则提高UserLoginSuccessEvent,如果不成功则提高UserLoginFailureEvent
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private readonly SignInManager<ApplicationUser> _signInManager;
private IEventService _events;
private readonly IHttpContextAccessor _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<ResourceOwnerPasswordValidator<ApplicationUser>> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="ResourceOwnerPasswordValidator{TUser}"/> class.
/// </summary>
/// <param name="userManager">The user manager.</param>
/// <param name="signInManager">The sign in manager.</param>
/// <param name="events">The events.</param>
/// <param name="logger">The logger.</param>
public ResourceOwnerPasswordValidator(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEventService events,
ILogger<ResourceOwnerPasswordValidator<ApplicationUser>> logger, IHttpContextAccessor context)
{
_userManager = userManager;
_signInManager = signInManager;
_events = events;
_logger = logger;
_context = context;
}
//this is used to validate your user account with provided grant at /connect/token
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
{
var user = await _userManager.FindByNameAsync(context.UserName);
if (user == null) user = await _userManager.FindByEmailAsync(context.UserName);
if (user != null)
{
//
var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password, true);
if (result.Succeeded)
{
_logger.LogInformation("Credentials validated for username: {username}", context.UserName);
await _events.RaiseAsync(new UserLoginSuccessEvent(context.UserName, user.Id, context.UserName, interactive: false));
context.Result = new GrantValidationResult(user.Id, AuthenticationMethods.Password);
return;
}
else if (result.IsLockedOut)
{
_logger.LogInformation("Authentication failed for username: {username}, reason: locked out", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "locked out", interactive: false));
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidRequest, "account is locked out try after 5 min");
return;
}
else if (result.IsNotAllowed)
{
_logger.LogInformation("Authentication failed for username: {username}, reason: not allowed", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "not allowed", interactive: false));
}
else
{
_logger.LogInformation("Authentication failed for username: {username}, reason: invalid credentials", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid credentials", interactive: false));
}
}
else
{
_logger.LogInformation("No user found matching username: {username}", context.UserName);
await _events.RaiseAsync(new UserLoginFailureEvent(context.UserName, "invalid username", interactive: false));
}
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
}
}
}