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认证服务器就搭好了 View Code
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的文件,再在配置文件中,添加数据库链接字符串 View Code
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 }
View Code1 { 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中的配置信息写入到数据库中去 View Code
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