.Net5 IdentityServer4下SqlServer和Mysql數據遷移


 

 

 

1.概念

以下概念從官網整理的,我也是看官網一步一步學習的

官網地址 https://identityserver4.readthedocs.io/en/latest/index.html

1.1 IdentityServer 是將符合規范的 OpenID Connect 和 OAuth 2.0 端點添加到任意 ASP.NET Core 應用程序的中間件。

IdentityServer 是一個 OpenID Connect 提供者——它實現了 OpenID Connect 和 OAuth 2.0 協議。

1.2 IdentityServer 能做什么

  • 保護您的資源
  • 使用本地帳戶存儲或通過外部身份提供商對用戶進行身份驗證
  • 提供會話管理和單點登錄
  • 管理和驗證客戶
  • 向客戶端頒發身份和訪問令牌
  • 驗證令牌

1.3 身份服務器:IdentityServer 是一個 OpenID Connect 提供者——它實現了 OpenID Connect 和 OAuth 2.0 協議。

1.4 用戶:用戶是使用注冊客戶端訪問資源的人。

1.5 客戶:客戶端是一個從 IdentityServer 請求令牌的軟件——用於驗證用戶(請求身份令牌)或訪問資源(請求訪問令牌)。客戶端必須先向 IdentityServer 注冊,然后才能請求令牌。

1.7 資源:資源是您想要使用 IdentityServer 保護的東西——您的用戶的身份數據或 API。

1.8 身份令牌:身份令牌代表身份驗證過程的結果。它至少包含用戶的標識符(稱為sub又名主題聲明)以及有關用戶如何以及何時進行身份驗證的信息。它可以包含額外的身份數據。

1.9 訪問令牌:訪問令牌允許訪問 API 資源。客戶端請求訪問令牌並將它們轉發到 API。訪問令牌包含有關客戶端和用戶(如果存在)的信息。API 使用該信息來授權對其數據的訪問。

 

2.安裝IdentityServer模板及數據庫遷移

2.1 安裝命令 dotnet new -i IdentityServer4.Templates

2.2 所需依賴包

<ItemGroup>
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="4.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.6">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
</ItemGroup>

2.3 創建項目模板 (依次執行以下命令)

創建項目模板

md MyIdentityServer4DataMigration

cd MyIdentityServer4DataMigration

md src

cd src

dotnet new is4empty -n IdentityServerBySqlServer

dotnet new is4empty -n IdentityServerByMySql

cd ../

dotnet new sln -n MyIdentityServer4DataMigration

dotnet sln add .\src\IdentityServerBySqlServer\IdentityServerBySqlServer.csproj

dotnet sln add .\src\IdentityServerByMySql\IdentityServerByMySql.csproj

創建完成后打開,如下如所示

 

 然后安裝依賴包,首先是sqlserver的

把上面的依賴包命令粘貼到IdentityServerBySqlServer.csproj里,control+s保存,會自動安裝依賴包

然后

cd src

dotnet new is4ui

大部分包我是通過Nuget手動安裝的,命令沒有那么全,SqlServer相關依賴包安裝完成后如下圖所示

 

 3. Startup代碼

3.1sqlserver代碼

public class Startup
    {
        public IWebHostEnvironment Environment { get; }

        public Startup(IWebHostEnvironment environment)
        {
            Environment = environment;
        }

        public void ConfigureServices(IServiceCollection services)
        {

            //var serverVersion = new MySqlServerVersion(new Version(8, 0, 21));

            //// Replace 'YourDbContext' with the name of your own DbContext derived class.
            //services.AddDbContext<YourDbContext>(
            //    dbContextOptions => dbContextOptions
            //        .UseMySql(connectionString, serverVersion)
            //        .EnableSensitiveDataLogging() // <-- These two calls are optional but help
            //        .EnableDetailedErrors()       // <-- with debugging (remove for production).
            //);

            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
            const string connectionString = @"Server=localhost; Port=3306;Stmt=; Database=MyIdentityServer4DB; Uid=root; Pwd=Docimax@123;";
            var serverVersion = new MySqlServerVersion(new Version(5, 7, 28));
            services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(connectionString,serverVersion));
            services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
            {
                options.User = new UserOptions
                {
                    RequireUniqueEmail = true, //要求Email唯一
                    AllowedUserNameCharacters = null //允許的用戶名字符
                };
                options.Password = new PasswordOptions
                {
                    RequiredLength = 8, //要求密碼最小長度,默認是 6 個字符
                    RequireDigit = true, //要求有數字
                    RequiredUniqueChars = 3, //要求至少要出現的字母數
                    RequireLowercase = true, //要求小寫字母
                    RequireNonAlphanumeric = false, //要求特殊字符
                    RequireUppercase = false //要求大寫字母
                };

                //options.Lockout = new LockoutOptions
                //{
                //    AllowedForNewUsers = true, // 新用戶鎖定賬戶
                //    DefaultLockoutTimeSpan = TimeSpan.FromHours(1), //鎖定時長,默認是 5 分鍾
                //    MaxFailedAccessAttempts = 3 //登錄錯誤最大嘗試次數,默認 5 次
                //};
                //options.SignIn = new SignInOptions
                //{
                //    RequireConfirmedEmail = true, //要求激活郵箱
                //    RequireConfirmedPhoneNumber = true //要求激活手機號
                //};
                //options.ClaimsIdentity = new ClaimsIdentityOptions
                //{
                //    // 這里都是修改相應的Cliams聲明的
                //    RoleClaimType = "IdentityRole",
                //    UserIdClaimType = "IdentityId",
                //    SecurityStampClaimType = "SecurityStamp",
                //    UserNameClaimType = "IdentityName"
                //};
            })
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();

            
            services.AddIdentityServer()
                  //.AddTestUsers(TestUsers.Users)
                .AddAspNetIdentity<ApplicationUser>()
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseMySql(connectionString, serverVersion,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseMySql(connectionString, serverVersion,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                });
        }

        public void Configure(IApplicationBuilder app)
        {
            InitializeDatabase(app);

            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // uncomment if you want to add MVC
            //app.UseStaticFiles();
            //app.UseRouting();

            app.UseIdentityServer();

            // uncomment, if you want to add MVC
            //app.UseAuthorization();
            //app.UseEndpoints(endpoints =>
            //{
            //    endpoints.MapDefaultControllerRoute();
            //});
        }

        private void InitializeDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

                var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
                context.Database.Migrate();
                if (!context.Clients.Any())
                {
                    foreach (var client in Config.Clients)
                    {
                        context.Clients.Add(client.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in Config.IdentityResources)
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.ApiScopes.Any())
                {
                    foreach (var resource in Config.ApiScopes)
                    {
                        context.ApiScopes.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }
            }
        }
    }

3.2 Mysql代碼

 public class Startup
    {
        public IWebHostEnvironment Environment { get; }

        public Startup(IWebHostEnvironment environment)
        {
            Environment = environment;
        }

        public void ConfigureServices(IServiceCollection services)
        {

            //var serverVersion = new MySqlServerVersion(new Version(8, 0, 21));

            //// Replace 'YourDbContext' with the name of your own DbContext derived class.
            //services.AddDbContext<YourDbContext>(
            //    dbContextOptions => dbContextOptions
            //        .UseMySql(connectionString, serverVersion)
            //        .EnableSensitiveDataLogging() // <-- These two calls are optional but help
            //        .EnableDetailedErrors()       // <-- with debugging (remove for production).
            //);

            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
            const string connectionString = @"Server=localhost; Port=3306;Stmt=; Database=MyIdentityServer4DB; Uid=root; Pwd=Docimax@123;";
            var serverVersion = new MySqlServerVersion(new Version(5, 7, 28));
            services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(connectionString,serverVersion));
            services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
            {
                options.User = new UserOptions
                {
                    RequireUniqueEmail = true, //要求Email唯一
                    AllowedUserNameCharacters = null //允許的用戶名字符
                };
                options.Password = new PasswordOptions
                {
                    RequiredLength = 8, //要求密碼最小長度,默認是 6 個字符
                    RequireDigit = true, //要求有數字
                    RequiredUniqueChars = 3, //要求至少要出現的字母數
                    RequireLowercase = true, //要求小寫字母
                    RequireNonAlphanumeric = false, //要求特殊字符
                    RequireUppercase = false //要求大寫字母
                };

                //options.Lockout = new LockoutOptions
                //{
                //    AllowedForNewUsers = true, // 新用戶鎖定賬戶
                //    DefaultLockoutTimeSpan = TimeSpan.FromHours(1), //鎖定時長,默認是 5 分鍾
                //    MaxFailedAccessAttempts = 3 //登錄錯誤最大嘗試次數,默認 5 次
                //};
                //options.SignIn = new SignInOptions
                //{
                //    RequireConfirmedEmail = true, //要求激活郵箱
                //    RequireConfirmedPhoneNumber = true //要求激活手機號
                //};
                //options.ClaimsIdentity = new ClaimsIdentityOptions
                //{
                //    // 這里都是修改相應的Cliams聲明的
                //    RoleClaimType = "IdentityRole",
                //    UserIdClaimType = "IdentityId",
                //    SecurityStampClaimType = "SecurityStamp",
                //    UserNameClaimType = "IdentityName"
                //};
            })
              .AddEntityFrameworkStores<ApplicationDbContext>()
              .AddDefaultTokenProviders();

            
            services.AddIdentityServer()
                  //.AddTestUsers(TestUsers.Users)
                .AddAspNetIdentity<ApplicationUser>()
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseMySql(connectionString, serverVersion,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseMySql(connectionString, serverVersion,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                });
        }

        public void Configure(IApplicationBuilder app)
        {
            InitializeDatabase(app);

            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // uncomment if you want to add MVC
            //app.UseStaticFiles();
            //app.UseRouting();

            app.UseIdentityServer();

            // uncomment, if you want to add MVC
            //app.UseAuthorization();
            //app.UseEndpoints(endpoints =>
            //{
            //    endpoints.MapDefaultControllerRoute();
            //});
        }

        private void InitializeDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

                var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
                context.Database.Migrate();
                if (!context.Clients.Any())
                {
                    foreach (var client in Config.Clients)
                    {
                        context.Clients.Add(client.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in Config.IdentityResources)
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }

                if (!context.ApiScopes.Any())
                {
                    foreach (var resource in Config.ApiScopes)
                    {
                        context.ApiScopes.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }
            }
        }
    }

 

4.數據遷移

第一種方式(推薦)

 1. vs2019 ===> 工具 ===> Nuget 包管理器 ====> 程序包管理器控制台
 2. 執行以下命令
 add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
 add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
 add-migration AppDbMigration -c ApplicationDbContext -o Data
 update-database -context PersistedGrantDbContext
 update-database -context ConfigurationDbContext
 update-database -context ApplicationDbContext

第二種方式

PowerShell執行數據遷移命令,然后運行程序

dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb

dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

遷移完成后如下圖所示

 

 檢查SqlServer數據庫是否生成表結構

 

 

//接下來操作mysql
cd ../

cd IdentityServerByMySql

dotnet new is4ui

dotnet add package IdentityServer4.EntityFramework

mysql的相關依賴包,如下圖所示:

 

 

dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb

dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb

MySql遷移完成后檢查MySql數據庫

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM