哈喽大家好,看见网上很少有使用MySql进行持久化的,毕竟又很多坑,说句实话,就连 MySql.Data.EntityFrameworkCore 都有问题,不知道是.net core更新太快还是其它的问题,但毕竟mssql驱动是没问题的,感觉还是私心太大了。不得以之下选择了一个第三方的驱动 Pomelo.EntityFrameworkCore.MySql 驱动,在这里主要是你安装了它,你就又了它的设计器,但你还需要你安装EFCore的设计器,因为你执行dotnet命令迁移的时候还得靠它,好吧,我们继续,在你的应用程序中最好保持这几个包。能多不能少。
就这样,在Model里创建两个类,一个是用户、一个是关系,这个是Identity的类。其实这个和IdentityServer是没有多大关系的。主要是为了扩展一些东西,比如你需要其它的字段?
public classApplicationRole : IdentityRole{}public class ApplicationUser : IdentityUser{}
随后我们定义IdentityDbContext,将我们自己定义的两个类放进去,它是个泛型的。
public class ApplicationDbContext : IdentityDbContext{public ApplicationDbContext(DbContextOptionsoptions)
:base(options)
{
}protected override voidOnModelCreating(ModelBuilder builder)
{base.OnModelCreating(builder);//Customize the ASP.NET Identity model and override the defaults if needed.//For example, you can rename the ASP.NET Identity table names and more.//Add your customizations after calling base.OnModelCreating(builder);
}
}
再之后我们就可以注入到.Net Core的服务里了,IdentityServer的数据库中有三个大类,有AspNet的票据用户、资源的管理、以及一些操作的记录。这里你可以用一个database,你也可以分开。
public voidConfigureServices(IServiceCollection services)
{//Add framework services.
services.AddDbContext(options =>options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();
services.AddMvc();string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddIdentityServer()
.AddConfigurationStore(options=>{
options.ConfigureDbContext= builder =>builder.UseMySql(Configuration.GetConnectionString("DefaultConnection"),
sql=>sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options=>{
options.ConfigureDbContext= builder =>builder.UseMySql(Configuration.GetConnectionString("DefaultConnection"),
sql=>sql.MigrationsAssembly(migrationsAssembly));//this enables automatic token cleanup. this is optional.
options.EnableTokenCleanup = true;
options.TokenCleanupInterval= 30;
});
}
随后注册IdentityServer服务,这个里面调用了 InitializeDatabase 方法为了初始化的迁移数据。
public voidConfigure(IApplicationBuilder app, IHostingEnvironment env)
{
InitializeDatabase(app);if(env.IsDevelopment())
app.UseDeveloperExceptionPage();elseapp.UseExceptionHandler("/Home/Error");app.UseIdentityServer();}
这个方法就很有意思了,获取了.net core的服务实例,然后对我的Context进行了更新迁移,直接将Config中的内存数据添加到了数据库中。
private voidInitializeDatabase(IApplicationBuilder app)
{using (var serviceScope = app.ApplicationServices.GetService().CreateScope())
{
serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();var context = serviceScope.ServiceProvider.GetRequiredService();
context.Database.Migrate();if (!context.Clients.Any())
{foreach (var client inConfig.GetClients())
{
context.Clients.Add(client.ToEntity());
}
context.SaveChanges();
}if (!context.IdentityResources.Any())
{foreach (var resource inConfig.GetIdentityResources())
{
context.IdentityResources.Add(resource.ToEntity());
}
context.SaveChanges();
}if (!context.ApiResources.Any())
{foreach (var resource inConfig.GetApiResources())
{
context.ApiResources.Add(resource.ToEntity());
}
context.SaveChanges();
}
}
最后你需要执行三个命令,执行EFCore的数据迁移。
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration-c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
dotnet ef migrations add InitialIdentityServerApplicationDbMigration-c ApplicationDbContext -o Data/Migrations/IdentityServer/ApplicationDb
就这样,生成完毕我们测试一下程序。
Ok,一些正常。