实现具有数据库访问权限的自定义IAuthorizationPolicyProvider

时间:2019-01-20 19:20:33

标签: c# asp.net-core

我正在使用asp.net core 2.1,我有一个IAuthorizationPolicyProvider的实现,它使用ctor注入来实现数据库上下文。由于必须将提供程序注册为单例,因此在确定数据库上下文的范围时会抛出该错误。

因此,我将连接字符串设置对象注入ctor中,然后使用选项构建器并在对GetPolicyAsync的调用内创建上下文:

var optionsBuilder = new DbContextOptionsBuilder<MyContext>();
optionsBuilder.UseSqlServer(this.connectionStrings.MyContextConnection);

using (var context = new MyContext(optionsBuilder.Options))
{
    // ...
}

用例在documentation的开头被调出,是否有一种安全有效的方法来在方法调用中获取上下文?

2 个答案:

答案 0 :(得分:2)

由于IServiceProvider没有方法CreateScope(),@ Tao Zhou的答案对我不起作用。

相反,我使用了ServiceProviderServiceExtensions类中的静态方法CreateScope()

using (var db = ServiceProviderServiceExtensions.CreateScope(_serviceProvider).ServiceProvider.GetRequiredService<ApplicationDbContext>())

答案 1 :(得分:0)

要从scoped service拯救singleton service,可以尝试在单例服务中注册IServiceProvider

public class DbPolicyProvider : IAuthorizationPolicyProvider
{
    private readonly IServiceProvider _serviceProvider;
    public DbPolicyProvider(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }
    public async Task<AuthorizationPolicy> GetDefaultPolicyAsync()
    {
        return await GetPolicyAsync("DbPolicy");
    }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        using (var db = _serviceProvider.CreateScope().ServiceProvider.GetRequiredService<ApplicationDbContext>())
        {
            var policys = db.Policys.Where(p => p.Name == policyName).ToList();
            var build = new AuthorizationPolicyBuilder();
            foreach (var policy in policys)
            {
                build.RequireClaim(policyName, policy.Config);
            }
            return Task.FromResult(build.Build());
        }
    }
}