文章簡介
-
asp.net core的空Web項目集成相關dll和頁面文件配置IdnetityServer4認證服務器
-
Ids4集成Identity
-
Ids4配置持久化到數據庫
寫在最前面,此文章不詳細講述IdentityServer4的各個組成部分以及Oauth2相關知識,需要了解詳細相關知識的,可以移步我的其他幾篇博客(初探IdentityServer4),騰訊視頻有Dave老師錄制的詳細教程(http://v.qq.com/vplus/4cfb00af75c16eb8d198c58fb86eb4dc?page=video)。
asp.net core的空Web項目集成相關dll和頁面文件配置IdnetityServer4認證服務器
- 首先創建一個net core版本為2.2的空項目,如下圖所示。引入IdntityServer4和Identity的相關Nuget包 IdentityServer4,IdentityServer4.AspNetIdentity,IdentityServer4.EntityFramework,Microsoft.EntityFrameworkCore.Sqlite(數據庫我們用Sqlite)。入下圖所示
- 添加靜態文件(wwwroot)和IdentityServer4的登錄UI以及控制器相關類(官方文檔的Quickstart),添加一個IdentityResource,ApiResource,和Client配置的Config類;因為Quickstart中用到的User類是繼承自IdnetityUser的ApplicationUser,所以我們添加一個ApplicationUser類;項目路徑是這樣的:
- 接下來我們配置startup文件,這樣,基於內存配置的(Config文件)我們的IdentityServer4認證服務器就搭好了
1 public class Startup 2 { 3 public IConfiguration Configuration { get; } 4 public IHostingEnvironment Environment { get; } 5 public Startup(IConfiguration configuration, IHostingEnvironment environment) 6 { 7 Configuration = configuration; 8 Environment = environment; 9 } 10 public void ConfigureServices(IServiceCollection services) 11 { 12 services.AddMvcCore() 13 .AddAuthorization() 14 .AddJsonFormatters(); 15 16 services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1); 17 18 19 20 services.Configure<IISOptions>(iis => 21 { 22 iis.AuthenticationDisplayName = "Windows"; 23 iis.AutomaticAuthentication = false; 24 }); 25 26 27 var builder = services.AddIdentityServer(options => 28 { 29 options.Events.RaiseErrorEvents = true; 30 options.Events.RaiseInformationEvents = true; 31 options.Events.RaiseFailureEvents = true; 32 options.Events.RaiseSuccessEvents = true; 33 }) 34 .AddInMemoryIdentityResources(Config.GetIdentityResources()) 35 .AddInMemoryApiResources(Config.GetApis()) 36 .AddInMemoryClients(Config.GetClients()) 37 .AddTestUsers(Config.GetUsers()); 38 39 if (Environment.IsDevelopment()) 40 { 41 builder.AddDeveloperSigningCredential(); 42 } 43 else 44 { 45 throw new Exception("need to configure key material"); 46 } 47 } 48 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 49 { 50 if (Environment.IsDevelopment()) 51 { 52 app.UseDeveloperExceptionPage(); 53 app.UseDatabaseErrorPage(); 54 } 55 else 56 { 57 app.UseExceptionHandler("/Home/Error"); 58 } 59 app.UseStaticFiles(); 60 app.UseMvcWithDefaultRoute(); 61 } 62 63 } 64 }
Ids4集成Identity
- 首先,添加一個數據庫上下文,這里我們使用sqlite數據庫,在項目根路徑下添加一個叫做identity.db的文件,再在配置文件中,添加數據庫鏈接字符串
1 public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 2 { 3 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } 4 protected override void OnModelCreating(ModelBuilder builder) 5 { 6 base.OnModelCreating(builder); 7 } 8 }
1 { 2 "ConnectionStrings": { 3 "DefaultConnection": "Data Source=identity.db;" 4 } 5 }
- 添加Identity的項目基架,選擇上一步添加的數據庫鏈接上下文
- 修改startup,配置Idnetity相關信息
-
最后,添加Identity的數據庫遷移文件,更新數據庫
1 Add-Migration CreateIdentitySchema 2 3 Update-Database
Ids4配置持久化到數據庫
- 到現在為止,我們已經把Identity集成到IdentityServer4認證服務器中去了,但是我們的保護資源配置(Config.cs),還是在內存中靜態的存在,接下來,我們把它持久化到數據庫中。首先,修改ConfigureServices方法,將從Config.cs中獲取Client和Resource的方法注釋掉,替換成下圖所示,其中ConfigurationStore包含了Cient,ApiResource,IdentityResource等信息,OperationalStore包含了用戶登錄時候生成的token信息
- 將Config中的配置信息寫入到數據庫中去
1 private void InitializeDatabase(IApplicationBuilder app) 2 { 3 using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 4 { 5 serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); 6 7 var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); 8 context.Database.Migrate(); 9 if (!context.Clients.Any()) 10 { 11 foreach (var client in Config.GetClients()) 12 { 13 context.Clients.Add(client.ToEntity()); 14 } 15 context.SaveChanges(); 16 } 17 if (!context.IdentityResources.Any()) 18 { 19 foreach (var resource in Config.GetIdentityResources()) 20 { 21 context.IdentityResources.Add(resource.ToEntity()); 22 } 23 context.SaveChanges(); 24 } 25 if (!context.ApiResources.Any()) 26 { 27 foreach (var resource in Config.GetApis()) 28 { 29 context.ApiResources.Add(resource.ToEntity()); 30 } 31 context.SaveChanges(); 32 } 33 } 34 }
- 分別為兩個數據庫上下文執行數據庫遷移命令,此時,數據庫中將多出這樣幾張表,紅色的框是ConfigurationDbContext生成的,綠的框是PersistedGrantDbContext生成的。最后別忘了把初始化配置種子數據的方法(InitializeDatabase)放到Configure執行下
1 private void InitializeDatabase(IApplicationBuilder app) 2 { 3 using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope()) 4 { 5 serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate(); 6 7 var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>(); 8 context.Database.Migrate(); 9 if (!context.Clients.Any()) 10 { 11 foreach (var client in Config.GetClients()) 12 { 13 context.Clients.Add(client.ToEntity()); 14 } 15 context.SaveChanges(); 16 } 17 if (!context.IdentityResources.Any()) 18 { 19 foreach (var resource in Config.GetIdentityResources()) 20 { 21 context.IdentityResources.Add(resource.ToEntity()); 22 } 23 context.SaveChanges(); 24 } 25 if (!context.ApiResources.Any()) 26 { 27 foreach (var resource in Config.GetApis()) 28 { 29 context.ApiResources.Add(resource.ToEntity()); 30 } 31 context.SaveChanges(); 32 } 33 } 34 }
- 最后,運行起來看下效果:我們注冊一個用戶,登錄下
- 示例Demo=》https://github.com/madeinchinalmc/IdentityServer4Sample.git