You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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本身提供了一套实体基类(比如ClientApiResource这些在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.csConfigureServices方法,把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

火山引擎 最新活动