identityServer4 使用mysql数据库持久化
一、使用dotnet new is4inmem --name Sqr.Passport命令创建项目模板

二、安装相关包
install-package Pomelo.EntityFrameworkCore.MySql
install-package MySql.Data.EntityFrameworkCore
三、新建ApplicationDbContext及相关model
1 public class ApplicationDbContext : DbContext 2 { 3 public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) 4 { 5 6 } 7 8 protected override void OnModelCreating(ModelBuilder builder) 9 { 10 base.OnModelCreating(builder); 11 // Customize the ASP.NET Identity model and override the defaults if needed. 12 // For example, you can rename the ASP.NET Identity table names and more. 13 // Add your customizations after calling base.OnModelCreating(builder); 14 } 15 16 public DbSet<M_ApplicationUser> ApplicationUser { get; set; } 17 18 public DbSet<M_IdentityRole> IdentityRole { get; set; } 19 20 public DbSet<M_IdentityRoleClaim> IdentityRoleClaim { get; set; } 21 22 public DbSet<M_IdentityUserClaim> IdentityUserClaim { get; set; } 23 24 public DbSet<M_IdentityUserLogin> IdentityUserLogin { get; set; } 25 26 public DbSet<M_IdentityUserRole> IdentityUserRole { get; set; } 27 28 public DbSet<M_IdentityUserToken> IdentityUserToken { get; set; } 29 }
四、startup修改为如下代码:
1 public class Startup 2 { 3 public IWebHostEnvironment Environment { get; } 4 public IConfiguration Configuration { get; } 5 6 public Startup(IWebHostEnvironment environment, IConfiguration configuration) 7 { 8 Environment = environment; 9 Configuration = configuration; 10 } 11 12 public void ConfigureServices(IServiceCollection services) 13 { 14 string connectionString = Configuration.GetConnectionString("DefaultConnection"); 15 var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; 16 17 services.AddControllersWithViews(); 18 19 services.AddDbContext<ApplicationDbContext>(options => 20 options.UseMySQL(connectionString)); 21 22 23 24 var builder = services.AddIdentityServer(options => 25 { 26 options.Events.RaiseErrorEvents = true; 27 options.Events.RaiseInformationEvents = true; 28 options.Events.RaiseFailureEvents = true; 29 options.Events.RaiseSuccessEvents = true; 30 31 // see https://identityserver4.readthedocs.io/en/latest/topics/resources.html 32 options.EmitStaticAudienceClaim = true; 33 }) 34 35 .AddConfigurationStore(opt => 36 { 37 opt.ConfigureDbContext = context => 38 { 39 context.UseMySQL(connectionString, sql => 40 { 41 sql.MigrationsAssembly(migrationsAssembly); 42 }); 43 }; 44 }) 45 .AddOperationalStore(opt => 46 { 47 opt.ConfigureDbContext = context => 48 { 49 context.UseMySQL(connectionString, sql => 50 { 51 sql.MigrationsAssembly(migrationsAssembly); 52 }); 53 }; 54 opt.EnableTokenCleanup = true; 55 opt.TokenCleanupInterval = 30; 56 }) 57 .AddTestUsers(TestUsers.Users); 58 59 // not recommended for production - you need to store your key material somewhere secure 60 builder.AddDeveloperSigningCredential(); 61 62 services.AddAuthentication() 63 .AddGoogle(options => 64 { 65 options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; 66 67 // register your IdentityServer with Google at https://console.developers.google.com 68 // enable the Google+ API 69 // set the redirect URI to https://localhost:5001/signin-google 70 options.ClientId = "copy client ID from Google here"; 71 options.ClientSecret = "copy client secret from Google here"; 72 }); 73 } 74 75 public void Configure(IApplicationBuilder app) 76 { 77 if (Environment.IsDevelopment()) 78 { 79 app.UseDeveloperExceptionPage(); 80 } 81 82 app.UseStaticFiles(); 83 84 app.UseRouting(); 85 app.UseIdentityServer(); 86 app.UseAuthorization(); 87 app.UseEndpoints(endpoints => 88 { 89 endpoints.MapDefaultControllerRoute(); 90 }); 91 } 92 }
五、执行命令迁移数据
1、add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/PersistedGrantDb
2、add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/ConfigurationDb
3、add-migration InitialIApplicationDbMigration -c ApplicationDbContext -o Data/Migrations/ApplicationDb
4、update-database -Context PersistedGrantDbContext
5、update-database -Context ConfigurationDbContext
6、update-database -Context ApplicationDbContext
六、安装consul
注册服务
1 public sealed class ConsulRegistry 2 { 3 4 public static IConfiguration Configuration { get; private set; } 5 6 static ConsulRegistry() 7 { 8 var fileDir=new PhysicalFileProvider(Directory.GetCurrentDirectory()); 9 10 Configuration = new ConfigurationBuilder().SetBasePath(fileDir.Root).AddJsonFile("appsettings.json", false, true).Build(); 11 } 12 13 14 /// <summary> 15 /// 需要注册的服务地址 16 /// </summary> 17 public static string ConsulServiceIP 18 { 19 get 20 { 21 return Configuration["Consul:ServiceIP"]; 22 } 23 } 24 25 /// <summary> 26 /// 需要注册的服务端口 27 /// </summary> 28 public static int ConsulServicePort 29 { 30 get 31 { 32 string str = Configuration["Consul:ServicePort"]; 33 return int.Parse(str); 34 } 35 } 36 37 public static string ConsulAddress 38 { 39 get 40 { 41 return Configuration["Consul:Address"]; 42 } 43 } 44 45 /// <summary> 46 /// 服务注册 47 /// </summary> 48 public static void ConsulRegister() 49 { 50 ConsulClient client = new ConsulClient( 51 (ConsulClientConfiguration c) => 52 { 53 c.Address = new Uri(Configuration["Consul:Address"]); //Consul服务中心地址 54 c.Datacenter = Configuration["Consul:DataCenter"]; //指定数据中心,如果未提供,则默认为代理的数据中心。 55 } 56 ); 57 string checkUrl = Configuration["Consul:CheckUrl"]; 58 client.Agent.ServiceRegister(new AgentServiceRegistration() 59 { 60 ID = Guid.NewGuid().ToString(), //服务编号,不可重复 61 Name = Configuration["Consul:ServiceName"], //服务名称 62 Port = ConsulServicePort, //本程序的端口号 63 Address = ConsulServiceIP, //本程序的IP地址 64 Check = new AgentServiceCheck() 65 { 66 DeregisterCriticalServiceAfter = TimeSpan.FromMilliseconds(1), //服务停止后多久注销 67 Interval = TimeSpan.FromSeconds(5), //服务健康检查间隔 68 Timeout = TimeSpan.FromSeconds(5), //检查超时的时间 69 HTTP = $"http://{ConsulServiceIP}:{ConsulServicePort}{checkUrl}" //检查的地址 70 } 71 }); 72 } 73 74 /// <summary> 75 /// 获取服务 76 /// </summary> 77 public static string GetService(string serviceName) 78 { 79 ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); 80 81 var response = client.Agent.Services().Result.Response; 82 83 //服务名称区分大小写,若要不区分:Equals(serviceName, StringComparison.OrdinalIgnoreCase) 84 var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); 85 86 //进行取模,随机取得一个服务器,或者使用其它负载均衡策略 87 var service = services.ElementAt(Environment.TickCount % services.Count()); 88 89 return service.Address + ":" + service.Port; 90 } 91 92 /// <summary> 93 /// 获取服务(异步方法) 94 /// </summary> 95 public async Task<string> GetServiceAsync(string serviceName) 96 { 97 ConsulClient client = new ConsulClient(c => c.Address = new Uri(ConsulAddress)); 98 99 var response = (await client.Agent.Services()).Response; 100 101 //服务名称区分大小写,若要不区分:Equals(serviceName, StringComparison.OrdinalIgnoreCase) 102 var services = response.Where(s => s.Value.Service.Equals(serviceName)).Select(s => s.Value); 103 104 //进行取模,随机取得一个服务器,或者使用其它负载均衡策略 105 var service = services.ElementAt(Environment.TickCount % services.Count()); 106 107 return service.Address + ":" + service.Port; 108 } 109 110 public static string HttpGetString(string url) 111 { 112 HttpClient httpClient = new HttpClient(); 113 string result = httpClient.GetAsync(url) 114 .Result.Content.ReadAsStringAsync().Result; 115 httpClient.Dispose(); 116 return result; 117 } 118 119 public static T HttpGetObject<T>(string url) 120 { 121 string result = HttpGetString(url); 122 return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result); 123 } 124 }
在startup->ConfigureServices里加如注册调用
ConsulRegistry.ConsulRegister();

浙公网安备 33010602011771号