如何让 IdentityServer 与 AddDbContextPool 一起工作

Posted

技术标签:

【中文标题】如何让 IdentityServer 与 AddDbContextPool 一起工作【英文标题】:How to get IdentityServer to work with AddDbContextPool 【发布时间】:2020-12-13 13:17:26 【问题描述】:

我正在尝试在使用 IdentityServer 进行身份验证的 ASP Core API 项目中利用 AddDBContextPool。问题是,要使用 PersistedGrants,您需要以这种方式设置 DBContext:

private readonly IOptions<OperationalStoreOptions> _operationalStoreOptions;

public ApplicationDbContext(
   DbContextOptions options,
   IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options)
   
        _operationalStoreOptions = operationalStoreOptions;
   
    
protected override void OnModelCreating(ModelBuilder builder)

    base.OnModelCreating(builder);
    builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value);

AddDBContextPool 只需要一个仅将 DbContextOptions 作为参数的构造函数。所以我不能再注入operationalStoreOptions了。

我尝试使用 Startup 类中的 AddOperationalStore(),但出现以下错误:

实体类型“DeviceFlowCodes”需要一个主键 定义。如果您打算使用无键实体类型调用 'HasNoKey()'。

知道我错过了什么吗?

【问题讨论】:

这是link,你可以看到Stevegreatrex说Looks like ApiAuthorizationDbContext specifies a primary key for DeviceFlowCodes (and other types) which - by overriding - I had removed. Add base.OnModelCreating(modelBuilder) to the top of the method and everything starts working again 谢谢依依。我确实看到了这个链接,但不幸的是我已经调用了 base.OnModelCreating()。不过还是不行。 【参考方案1】:

我最终在我的班级中手动实现了 IPersistedGrantDbContext 接口。代码如下,以防对其他人有帮助。

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>, IPersistedGrantDbContext
    
        public ApplicationDbContext(DbContextOptions options) : base(options)
        
            // No tracking needed as all transactions are disconnected
            ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        

        public DbSet<PersistedGrant> PersistedGrants  get; set;  = null!;
        public DbSet<DeviceFlowCodes> DeviceFlowCodes  get; set;  = null!;

        public Task<int> SaveChangesAsync()
        
            return base.SaveChangesAsync();
        

        protected override void OnModelCreating(ModelBuilder builder)
        
            OperationalStoreOptions options = new OperationalStoreOptions
            
                DeviceFlowCodes = new TableConfiguration("DeviceCodes"),
                PersistedGrants = new TableConfiguration("PersistedGrants")
            ;

            base.OnModelCreating(builder);
            builder.ConfigurePersistedGrantContext(options);
            
            // ... Rest of configuration here

        
    

【讨论】:

以上是关于如何让 IdentityServer 与 AddDbContextPool 一起工作的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IdentityServer4 上添加电话号码声明

使用 IdentityServer3 生成访问令牌,无需密码

IdentityServer4 客户端范围和基于用户声明的授权

IdentityServer4主题之授权类型

如何在 Startup 中将选项模式与这些服务一起使用?

IdentityServer4实战 - 与API单项目整合