ASP.NET Core 6中如何给基于特性的自定义授权类注入依赖
在ASP.NET Core 6 Web API中给自定义授权特性注入DbContext
你当前的写法存在问题——特性是编译时实例化的,没法通过构造函数直接注入依赖(包括IServiceProvider)。正确的做法是在OnAuthorization方法里,从请求上下文的服务容器中获取DbContext,具体操作如下:
修改自定义授权特性
删掉特性里的IServiceProvider字段和带参构造函数,直接在授权方法内获取服务:
[AttributeUsage(AttributeTargets.Class)] public class CustomAuthorization : Attribute, IAuthorizationFilter { public void OnAuthorization(AuthorizationFilterContext filterContext) { // 从HttpContext的服务容器中获取DbContext实例 var dbContext = filterContext.HttpContext.RequestServices.GetRequiredService<YourDbContext>(); // 此处可直接使用dbContext操作数据库 // 示例:var targetData = dbContext.YourEntitySet.FirstOrDefault(...); } }
异步场景优化
如果需要执行异步数据库操作,建议改用IAsyncAuthorizationFilter接口,避免阻塞请求线程:
[AttributeUsage(AttributeTargets.Class)] public class CustomAuthorization : Attribute, IAsyncAuthorizationFilter { public async Task OnAuthorizationAsync(AuthorizationFilterContext filterContext) { var dbContext = filterContext.HttpContext.RequestServices.GetRequiredService<YourDbContext>(); // 异步数据库操作示例 // var targetData = await dbContext.YourEntitySet.FirstOrDefaultAsync(...); } }
更推荐的方案:基于策略的授权
如果你的授权逻辑复杂,ASP.NET Core官方更推荐使用基于策略的授权(实现IAuthorizationHandler),这种方式原生支持依赖注入,更符合框架设计模式:
1. 定义授权需求
public class CustomAuthorizationRequirement : IAuthorizationRequirement { // 可在此添加需求相关的自定义参数 }
2. 实现授权处理器(支持构造注入DbContext)
public class CustomAuthorizationHandler : AuthorizationHandler<CustomAuthorizationRequirement> { private readonly YourDbContext _dbContext; // 直接通过构造函数注入DbContext public CustomAuthorizationHandler(YourDbContext dbContext) { _dbContext = dbContext; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomAuthorizationRequirement requirement) { // 使用_dbContext完成数据库操作与授权逻辑判断 // 逻辑通过后标记授权成功 context.Succeed(requirement); } }
3. 注册策略与处理器
在Program.cs中完成注册:
builder.Services.AddAuthorization(options => { options.AddPolicy("CustomAuthorization", policy => policy.Requirements.Add(new CustomAuthorizationRequirement())); }); builder.Services.AddScoped<IAuthorizationHandler, CustomAuthorizationHandler>();
4. 在控制器上应用策略
[Authorize(Policy = "CustomAuthorization")] public class OrganizationController : CustomControllerBaseClass { // 控制器业务逻辑 }
内容的提问来源于stack exchange,提问作者NSS
相关产品推荐
相关产品推荐

