如何在ASP.Net Core 2中自定义实体及数据库表,替代Identity Server 4默认生成内容?
在ASP.NET Core 2中为Identity Server 4创建自定义实体与数据库表
我之前在ASP.NET Core 2项目里折腾过这个需求——不想用Identity Server 4默认生成的那套实体和数据库表,得自己加字段、改表名。下面是我亲测有效的步骤,分享给你:
1. 先搞懂Identity Server 4的实体基础
Identity Server 4本身提供了一套实体基类(比如Client、ApiResource这些在IdentityServer4.EntityFramework.Entities命名空间下的类),我们的自定义实体必须继承这些基类,这样才能兼容Identity Server的核心逻辑,不能完全从零写。
2. 编写自定义实体类
举个例子,我想给Client表加个Description字段来存客户端的描述信息,就可以这么写:
using IdentityServer4.EntityFramework.Entities; public class CustomClient : Client { // 自定义字段 public string Description { get; set; } }
要是你需要自定义ApiResource、IdentityResource或者其他实体,都用同样的方式:继承对应的基类,再添加自己需要的属性就行。
3. 自定义DbContext
接下来要创建自己的DbContext,继承Identity Server的IdentityServerDbContext,并把我们的自定义实体传进去:
using IdentityServer4.EntityFramework.DbContexts; using IdentityServer4.EntityFramework.Options; using Microsoft.EntityFrameworkCore; public class CustomIdentityServerDbContext : IdentityServerDbContext<CustomClient> { public CustomIdentityServerDbContext(DbContextOptions<CustomIdentityServerDbContext> options, OperationalStoreOptions operationalStoreOptions) : base(options, operationalStoreOptions) { } // 要是还有其他自定义实体,比如CustomApiResource,记得加对应的DbSet // public DbSet<CustomApiResource> CustomApiResources { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 这里可以自定义表名、字段约束之类的配置 modelBuilder.Entity<CustomClient>().ToTable("CustomClients"); } }
4. 在Startup里替换默认服务
打开Startup.cs的ConfigureServices方法,把Identity Server默认使用的DbContext换成我们自己的:
public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration.GetConnectionString("IdentityServerDb"); // 注册自定义DbContext services.AddDbContext<CustomIdentityServerDbContext>(options => options.UseSqlServer(connectionString)); // 配置Identity Server,替换默认的配置存储实体 services.AddIdentityServer() .AddConfigurationStore(options => { options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(typeof(Startup).Assembly.GetName().Name)); // 指定我们的自定义Client实体 options.ClientEntity = typeof(CustomClient); // 如果自定义了ApiResource,这里也要指定 // options.ApiResourceEntity = typeof(CustomApiResource); }) .AddOperationalStore(options => { options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(typeof(Startup).Assembly.GetName().Name)); }) .AddDeveloperSigningCredential(); // 开发环境用这个,生产环境一定要换成正式的签名证书! }
5. 生成并执行数据库迁移
最后一步就是生成迁移脚本并更新数据库了。打开Package Manager Console或者命令行,执行:
# 创建迁移,指定我们的自定义DbContext Add-Migration InitialCustomIdentityServerSchema -Context CustomIdentityServerDbContext
然后更新数据库:
Update-Database -Context CustomIdentityServerDbContext
跑完之后,数据库里就会出现我们自定义的表(比如上面的CustomClients),里面既有Identity Server需要的所有默认字段,也有我们自己加的字段。
一些要注意的点
- 要是同时自定义多个实体(比如Client和ApiResource都改了),一定要在DbContext和
AddConfigurationStore里都正确指定对应的实体类型,不然会出问题。 - 执行迁移的时候,一定要指定对DbContext,别和项目里其他DbContext搞混了。
- 自定义实体的时候,别随便重写基类里的关键字段,比如
ClientId这种,不然会破坏Identity Server的核心逻辑。
内容的提问来源于stack exchange,提问作者routtor




