namespace MyOffice.Web.Auth; using Identity.Domain; using Identity.Repositories; using Microsoft.AspNetCore.Identity; using OpenIddict.Abstractions; using OpenIddict.Server; using OpenIddict.Server.AspNetCore; using static OpenIddict.Abstractions.OpenIddictConstants; using static OpenIddict.Server.OpenIddictServerEvents; public sealed class PasswordGrantHandler : IOpenIddictServerHandler { private readonly AppUserManager _userManager; private readonly SignInManager> _signInManager; public PasswordGrantHandler( AppUserManager userManager, SignInManager> signInManager ) { _userManager = userManager; _signInManager = signInManager; } public async ValueTask HandleAsync(HandleTokenRequestContext context) { if (!string.Equals(context.Request.GrantType, GrantTypes.Password, StringComparison.Ordinal)) return; var username = context.Request.Username?.Trim(); if (string.IsNullOrWhiteSpace(username)) { context.Reject(Errors.InvalidGrant, "Invalid username or password."); return; } var user = await _userManager.FindByNameAsync(username) ?? await _userManager.FindByEmailAsync(username); if (user is null) { context.Reject(Errors.InvalidGrant, "Invalid username or password."); return; } if (!await _signInManager.CanSignInAsync(user)) { context.Reject(Errors.InvalidGrant, "The specified user cannot sign in."); return; } if (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user)) { context.Reject(Errors.InvalidGrant, "The specified user is locked out."); return; } var result = await _signInManager.CheckPasswordSignInAsync(user, context.Request.Password!, lockoutOnFailure: true); if (!result.Succeeded) { context.Reject(Errors.InvalidGrant, "Invalid username or password."); return; } if (_userManager.SupportsUserLockout) await _userManager.ResetAccessFailedCountAsync(user); context.SignIn(OpenIddictClaimsHelper.CreatePrincipal(user, context.Request.GetScopes())); } }