You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Identity中实现用户登录服务并修正JWT认证相关代码

修正ASP.NET Identity登录服务与JWT生成流程(含密码验证)

以下是针对需求的完整代码修正方案,核心实现密码验证→JWT生成的完整流程,同时规范服务接口与逻辑:


1. 定义登录服务接口与结果类

先明确登录服务的契约,避免无意义的空接口:

public interface IUserLogin
{
    // 异步验证用户密码,返回验证结果
    Task<LoginValidationResult> ValidateUserCredentials(string userName, string password);
}

// 自定义登录验证结果,传递验证状态与用户信息
public class LoginValidationResult
{
    public bool IsValid { get; set; }
    public User? User { get; set; } // 验证成功时返回用户实体
}

2. 修正LoginService实现

修复原方法返回类型错误,正确使用Identity的密码验证逻辑:

public class LoginService : IUserLogin
{
    private readonly SignInManager<User> _signInManager;
    private readonly UserManager<User> _userManager; // 新增UserManager用于获取用户完整信息

    public LoginService(SignInManager<User> signInManager, UserManager<User> userManager)
    {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    public async Task<LoginValidationResult> ValidateUserCredentials(string userName, string password)
    {
        // 使用Identity原生方法验证密码
        var signInResult = await _signInManager.PasswordSignInAsync(
            userName, 
            password, 
            isPersistent: false, // JWT场景不需要持久化Cookie
            lockoutOnFailure: false
        );

        if (!signInResult.Succeeded)
        {
            return new LoginValidationResult { IsValid = false };
        }

        // 验证成功后获取用户完整实体,用于生成JWT Claims
        var user = await _userManager.FindByNameAsync(userName);
        return new LoginValidationResult 
        { 
            IsValid = true, 
            User = user 
        };
    }
}

3. 改造JWTAuthorizationManager:加入密码验证

原方法直接生成令牌,现在改为先验证密码再生成JWT:

public class JWTAuthorizationManager
{
    private readonly IUserLogin _loginService;
    private readonly UserManager<User> _userManager;

    // 通过依赖注入获取登录服务与用户管理器
    public JWTAuthorizationManager(IUserLogin loginService, UserManager<User> userManager)
    {
        _loginService = loginService;
        _userManager = userManager;
    }

    public async Task<JwtFeilds?> Authenticate(string userName, string password)
    {
        // 第一步:验证用户密码
        var validationResult = await _loginService.ValidateUserCredentials(userName, password);
        if (!validationResult.IsValid || validationResult.User == null)
        {
            return null; // 验证失败返回null,对应后续未授权
        }

        // 第二步:验证通过,生成JWT令牌
        var tokenExpireTimeStamp = DateTime.Now.AddHours(Constants.JWT_TOKEN_EXPIRE_TIME);
        var jwtHandler = new JwtSecurityTokenHandler();
        var tokenKey = Encoding.ASCII.GetBytes(Constants.JWT_SECURITY_KEY_FOR_TOKEN);

        // 从用户实体动态生成Claims(替代原硬编码内容)
        var claims = new List<Claim>
        {
            new Claim("username", validationResult.User.UserName!),
            new Claim(ClaimTypes.NameIdentifier, validationResult.User.Id)
        };

        // 可选:添加用户角色到Claims
        var userRoles = await _userManager.GetRolesAsync(validationResult.User);
        foreach (var role in userRoles)
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = tokenExpireTimeStamp,
            SigningCredentials = new SigningCredentials(
                new SymmetricSecurityKey(tokenKey), 
                SecurityAlgorithms.HmacSha256Signature
            )
        };

        var securityToken = jwtHandler.CreateToken(tokenDescriptor);
        var token = jwtHandler.WriteToken(securityToken);

        return new JwtFeilds
        {
            token = token,
            user_name = validationResult.User.UserName!,
            expire_time = (int)tokenExpireTimeStamp.Subtract(DateTime.Now).TotalSeconds
        };
    }
}

4. 修正Controller登录接口

改为异步处理,通过依赖注入获取服务,并添加模型验证:

[ApiController]
[Route("api/auth")]
public class AuthController : ControllerBase
{
    private readonly JWTAuthorizationManager _jwtManager;

    // 构造函数注入JWT管理器
    public AuthController(JWTAuthorizationManager jwtManager)
    {
        _jwtManager = jwtManager;
    }

    [HttpPost("login")]
    public async Task<IActionResult> Login([FromForm] User model)
    {
        // 先验证输入模型合法性
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var jwtResult = await _jwtManager.Authenticate(model.UserName, model.Password);
        return jwtResult == null ? Unauthorized() : Ok(jwtResult);
    }
}

5. 注册服务到DI容器

在Program.cs中添加服务注册:

// 注册登录服务
builder.Services.AddScoped<IUserLogin, LoginService>();
// 注册JWT授权管理器
builder.Services.AddScoped<JWTAuthorizationManager>();

内容的提问来源于stack exchange,提问作者sadegh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:35:14