- 使用DbContextSeed初始化数据库
- 添加链接字符串
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //添加链接字符串 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddMvc(); }
- 添加初始化数据类和方法
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace mvcforcookie.Data { using Models; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection;//CreateScope() public class ApplicationDbContextSeed { private UserManager<ApplicationUser> _userManager; public async Task SeedAsync(ApplicationDbContext context, IServiceProvider service) { if (!context.Users.Any()) { _userManager = service.GetRequiredService<UserManager<ApplicationUser>>(); //创建初始用户 var defultUser = new ApplicationUser() { UserName = "Administrator", Email = "453151742@qq.com", NormalizedUserName = "admin" }; var result = await _userManager.CreateAsync(defultUser, "Password$123"); if (!result.Succeeded) { throw new Exception("初始用户创建失败"); } } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace mvcforcookie.Data { using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; public static class WebHostMigrationExtensions { /// <summary> /// 初始化database方法 /// </summary> /// <typeparam name="TContext"></typeparam> /// <param name="host"></param> /// <param name="sedder"></param> /// <returns></returns> public static IWebHost MigrateDbContext<TContext>(this IWebHost host, Action<TContext, IServiceProvider> sedder) where TContext : ApplicationDbContext { //创建数据库实例在本区域有效 using (var scope=host.Services.CreateScope()) { var services = scope.ServiceProvider; var logger = services.GetRequiredService<ILogger<TContext>>(); var context = services.GetService<TContext>(); try { context.Database.Migrate();//初始化database sedder(context, services); logger.LogInformation($"执行DbContext{typeof(TContext).Name} seed 成功"); } catch ( Exception ex) { logger.LogError(ex, $"执行dbcontext {typeof(TContext).Name} seed失败"); } } return host; } } }
-
BuildWebHost时注入初始化函数
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace mvcforcookie { using mvcforcookie.Data; public class Program { public static void Main(string[] args) { BuildWebHost(args) .MigrateDbContext<ApplicationDbContext>((context, services) => { new ApplicationDbContextSeed().SeedAsync(context, services).Wait(); }) .Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
- 添加链接字符串
- 使用services注入初始化数据库
- 添加Nuget包IdentityServer4.EntityFramework
- 添加链接字符串初始化dbcontext
public void ConfigureServices(IServiceCollection services) { var connectionstr = "Server=(localdb)\mssqllocaldb;Database=IdentityServer4.EntityFramework;Trusted_Connection=True;MultipleActiveResultSets=true"; var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; // //添加identity services.AddIdentity<ApplicationUser, ApplicationUserRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddIdentityServer() .AddDeveloperSigningCredential()//添加证书 .AddConfigurationStore(options=> {//添加ConfigurationStore的配置存储claims options.ConfigureDbContext = builder => { builder.UseSqlServer(connectionstr, sql => sql.MigrationsAssembly(migrationAssembly)); }; }) .AddOperationalStore(options => {//添加OperationalStore的配置存储token的表格控制 options.ConfigureDbContext = builder => { builder.UseSqlServer(connectionstr, sql => sql.MigrationsAssembly(migrationAssembly)); }; }) .AddAspNetIdentity<ApplicationUser>()//添加identityuser .Services.AddScoped<IProfileService,ProfileService>();//添加profileservice services.AddMvc(); }
- 使用命令行初始化数据库
Add-Migration InitConfigurations -Context ConfigurationDbContext -OutputDir DataMigrationsIdentityServerConfiguration Add-Migration InitPersistedGrant -Context PersistedGrantDbContext -OutputDir DataMigrationsIdentityServerPersistedGrantDb DBcontext 在 Identityserver4.EntityFramwork.DbContexts 命名空间下 Update-Database -Context ConfigurationDbContext Update-Database -Context PersistedGrantDbContext
- 添加初始化数据的方法
using System.Collections.Generic; using System.Collections; using IdentityServer4.Models; using IdentityServer4.Test; using IdentityServer4; using System.Security.Claims; namespace mvcforcookie { public class Config { public static IEnumerable<ApiResource> GetApiResoure() { return new List<ApiResource>() { new ApiResource("api1", "My Api") }; } public static IEnumerable<IdentityServer4.Models.Client> GetClients() { return new List<IdentityServer4.Models.Client>() { //正常情况下配置在数据库当中 new IdentityServer4.Models.Client() { ClientId="MVC", ClientName="MVC", ClientUri="http://localhost:5001", LogoUri="https://www.nicepsd.com/image/ec3594cb9bd94e13a7078b5da254591e/image.jpg", AllowRememberConsent=true,//是否可以记住 //AllowedGrantTypes =GrantTypes.Implicit,//隐式 模式 AllowedGrantTypes =GrantTypes.HybridAndClientCredentials, RequireConsent=true,//用户是否要确认 ClientSecrets={new Secret("Secret".Sha256())},//密鑰 AllowAccessTokensViaBrowser=true, AllowOfflineAccess=true, RedirectUris={ "http://localhost:5001/signin-oidc"},//客户端 登陆的url PostLogoutRedirectUris={ "http://localhost:5001/signout-callback-oidc"},//登出地址 AlwaysIncludeUserClaimsInIdToken=true,//IdToken是否携带claims返回到客户端 AllowedScopes={ //使用identity4 IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile } } }; } public static List<TestUser> GetTestuser() { return new List<TestUser>(){new TestUser(){ SubjectId="10000", Username ="cyao", Password="oauth", Claims =new List<Claim>{ new Claim("name","cyao"), new Claim("webSite","www.baidu.com") } }}; } public static IEnumerable<IdentityResource> GetIdentityResource() { return new List<IdentityResource>(){ new IdentityResources.OpenId(), new IdentityResources.Profile() }; } } }
-
执行Init方法
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } //一定要先执行数据库生成命令然后执行初始化数据库 InitIdentityServerDataBase(app);//初始化数据库 app.UseStaticFiles(); // app.UseAuthentication(); app.UseIdentityServer(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } /// <summary> /// 初始化数据库 /// </summary> /// <param name="app"></param> public void InitIdentityServerDataBase(IApplicationBuilder app) { using (var scope=app.ApplicationServices.CreateScope()) { scope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); var configurationDbContext = scope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); if (!configurationDbContext.Clients.Any()) { foreach (var client in Config.GetClients()) { configurationDbContext.Clients.Add(client.ToEntity()); } configurationDbContext.SaveChanges(); } if (!configurationDbContext.ApiResources.Any()) { foreach (var api in Config.GetApiResoure()) { configurationDbContext.ApiResources.Add(api.ToEntity()); } configurationDbContext.SaveChanges(); } if (!configurationDbContext.IdentityResources.Any()) { foreach (var identity in Config.GetIdentityResource()) { configurationDbContext.IdentityResources.Add(identity.ToEntity()); } configurationDbContext.SaveChanges(); } } }