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

ASP.NET Core注册JwtAuthenticationManager时如何传入DatabaseContext参数

解决方案

你可以通过服务工厂重载的方式实现依赖注入,无需手动实例化DatabaseContext,具体实现分为两种场景:

场景1:允许将IJwtAuthenticationManager的生命周期调整为Scoped(推荐)

默认DatabaseContext的注册生命周期为Scoped,和请求生命周期一致,将认证服务也调整为Scoped可以避免生命周期不匹配的问题,注册代码如下:

var key = "This is my auth key";
// 用工厂方法从容器中获取已注册的DatabaseContext
services.AddScoped<IJwtAuthenticationManager>(sp => 
    new JwtAuthenticationManager(sp.GetRequiredService<DatabaseContext>(), key)
);

场景2:必须将IJwtAuthenticationManager注册为Singleton

如果必须使用单例生命周期,不能直接注入Scoped的DatabaseContext,否则会导致上下文在后续请求中被释放报错,需要修改JwtAuthenticationManager的实现,注入IServiceScopeFactory,每次调用Authenticate方法时主动创建作用域获取DatabaseContext:

第一步:修改JwtAuthenticationManager代码

private readonly string key;
private readonly IServiceScopeFactory _scopeFactory;

// 构造函数改为接收IServiceScopeFactory和密钥
public JwtAuthenticationManager(IServiceScopeFactory scopeFactory, string key)
{
    _scopeFactory = scopeFactory;
    this.key = key;
}

public string Authenticate(string username, string password)
{
    // 每次验证时创建独立作用域获取DatabaseContext
    using var scope = _scopeFactory.CreateScope();
    var context = scope.ServiceProvider.GetRequiredService<DatabaseContext>();
    
    var result = context.Credentials.FirstOrDefault(x => x.Username == username && x.Password == password);
    if (result == null) return null;

    var tokenHandler = new JwtSecurityTokenHandler();
    var tokenKey = Encoding.ASCII.GetBytes(key);
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[] {
                new Claim(ClaimTypes.Name, username)
            }),
        Expires = DateTime.UtcNow.AddHours(1),
        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(tokenKey),
            SecurityAlgorithms.HmacSha256Signature
        )
    };
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

第二步:注册单例服务

var key = "This is my auth key";
services.AddSingleton<IJwtAuthenticationManager>(sp => 
    new JwtAuthenticationManager(sp.GetRequiredService<IServiceScopeFactory>(), key)
);

提示:你原有代码中的JwtAuthenticationManager类漏写了private readonly DatabaseContext _context;字段定义,若选择场景1的方案记得先补全该字段。

内容的提问来源于stack exchange,提问作者Joel John Centeno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:27:04