.Net 5 IdentityServer4 数据持久化到 MySQL

本文档展示了如何在.NET Core应用中使用IdentityServer4进行身份验证服务配置,并结合MySQL数据库存储配置信息。详细步骤包括安装相关NuGet包,配置Startup类以连接MySQL,设置IdentityServer的资源、客户端和用户,以及执行数据库迁移操作。
摘要由CSDN通过智能技术生成

方法一:

NuGet 引入包  

IdentityServer4       3.1.4

IdentityServer4.EntityFramework       3.1.4

Microsoft.EntityFrameworkCore

Microsoft.EntityFrameworkCore.Design

Microsoft.EntityFrameworkCore.Relational

Microsoft.EntityFrameworkCore.Tools

Pomelo.EntityFrameworkCore.MySql       预发行版 5.0.0-alpha.2

下面直接贴代码

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddIdentityServer()
            //    //默认的开发者证书模式
            //    .AddDeveloperSigningCredential()
            //    //添加API资源作用域
            //    .AddInMemoryApiResources(IdentityConfig.IdentityConfig.GetApiScopes())
            //    //添加授权客户端
            //    .AddInMemoryClients(IdentityConfig.IdentityConfig.GetClients())
            //    //添加授权用户
            //    .AddTestUsers(IdentityConfig.IdentityConfig.GetTestUsers())
            //    //验证身份信息授权资源
            //    .AddInMemoryIdentityResources(IdentityConfig.IdentityConfig.IdentityResources)
            //    //解决 账户密码 模式 Claims 不携带的问题
            //    .AddProfileService<ProfileService>();


            #region Identity Mysql

            string connection = @"server=192.168.1.120;port=3306;database=IDS4;user=idsadmin;password=dev;";
            //services.AddDbContext<DbContext>(options => options.UseMySQL(connection));
            //services.AddDbContext<DbContext>(options => options.UseMySQL(GlobalAppConfig.myConfig.DbCon));

            var builder = services.AddIdentityServer()
                //身份信息资源
                //.AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddConfigurationStore(opt =>
                {
                    opt.ConfigureDbContext = context =>
                    {
                        context.UseMySql(connection, ServerVersion.AutoDetect(connection), sql =>
                         {
                             sql.MigrationsAssembly("IDS4");
                         });
                    };
                })
                .AddOperationalStore(opt =>
                {
                    opt.ConfigureDbContext = context =>
                    {
                        context.UseMySql(connection, ServerVersion.AutoDetect(connection), sql =>
                         {
                             sql.MigrationsAssembly("IDS4");
                         });
                    };
                    opt.EnableTokenCleanup = true;
                    opt.TokenCleanupInterval = 30;
                })
                .AddTestUsers(IdentityConfig.IdentityConfig.GetTestUsers());


            #endregion
              
            services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "IDS4", Version = "v1" });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "IDS4 v1"));
            }

            app.UseIdentityServer();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            ConsulHelper.ConsulRegist("http://192.168.1.234:8561/", "IDS4", "dev_dc", "192.168.1.162", 52838, 1);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls("http://*:52838");
                    webBuilder.UseStartup<Startup>();
                });
    }

public class IdentityConfig
    {
        /// <summary>
        /// 验证资源--用户信息
        /// </summary>
        public static IEnumerable<IdentityResource> IdentityResources =>
           new IdentityResource[]
           {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResource("TestResource","TestResource_DS",new List<string>{"Claim1","Claim2" })
           };

        /// <summary>
        /// Authorization Server保护了哪些 API Scope(作用域)
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<ApiResource> GetApiScopes()
        {
            return new[] { new ApiResource("testApi") };
            //return new[] { new ApiResource("testApi",new List<string> { "role" }) }; //自定义要传递的 Cliam
        }

        /// <summary>
        /// 哪些客户端 Client(应用) 可以使用这个 Authorization Server
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<Client> GetClients()
        {
            return new[]
            {
                //账户密码模式
                new Client()
                {
                    //客户端的标识,要是惟一的
                    ClientId="TestPWD",
                    //客户端密码,进行了加密
                    ClientSecrets=new []{new Secret("123456".Sha256())},
                    //授权方式账户密码
                    AllowedGrantTypes= GrantTypes.ResourceOwnerPassword,
                    //定义这个客户端可以访问的APi资源数组
                    AllowedScopes=new[]{"testApi" },

                    //AlwaysIncludeUserClaimsInIdToken=true
                },
                //客户端模式
                new Client()
                {
                    //客户端的标识,要是惟一的
                    ClientId="TestClient",
                    //客户端密码,进行了加密
                    ClientSecrets=new []{new Secret("TestSecret".Sha256())},
                    //授权方式,这里采用的是客户端认证模式,只要ClientId,以及ClientSecrets正确即可访问对应的AllowedScopes里面的api资源
                    AllowedGrantTypes= GrantTypes.ClientCredentials,
                    //定义这个客户端可以访问的APi资源数组
                    AllowedScopes=new[]{"testApi" },
                    //携带的自定义信息
                    Claims=new List<Claim> {
                        new Claim(IdentityModel.JwtClaimTypes.Role,"DevClient"),
                        new Claim(IdentityModel.JwtClaimTypes.NickName,"TestDev")
                    }
                },
                隐藏模式----二次跳转
                //new Client()
                //{
                //    //客户端的标识,要是惟一的
                //    ClientId="TestImplicit",
                //    //客户端密码,进行了加密
                //    ClientSecrets=new []{new Secret("123456".Sha256())},
                //    //授权方式---隐藏模式
                //    AllowedGrantTypes= GrantTypes.Implicit,
                //    RedirectUris={ "http://192.168.1.162:60000/DevService01/api/Test2"},
                //    //定义这个客户端可以访问的APi资源数组
                //    AllowedScopes=new[]{"testApi" },
                //    //允许将Token通过浏览器传递
                //    AllowAccessTokensViaBrowser=true
                //},
                //授权码模式
                //new Client()
                //{
                //    //客户端的标识,要是惟一的
                //    ClientId="TestCode",
                //    //客户端密码,进行了加密
                //    ClientSecrets=new []{new Secret("123456".Sha256())},
                //    //授权方式---隐藏模式
                //    AllowedGrantTypes= GrantTypes.Code,
                //    RedirectUris={ "http://192.168.1.162:60000/DevService01/api/Test2"},
                //    //定义这个客户端可以访问的APi资源数组
                //    AllowedScopes=new[]{"testApi" },
                //    //允许将Token通过浏览器传递
                //    AllowAccessTokensViaBrowser=true
                //},
                //混合模式
                new Client()
                {
                    //客户端的标识,要是惟一的
                    ClientId="TestHybrid",
                    //客户端密码,进行了加密
                    ClientSecrets=new []{new Secret("123456".Sha256())},
                    //授权方式---隐藏模式
                    ClientName="TestHybrid                                                                                                                                                                                                                                                                                                                                                                                                                                              ",
                    AllowedGrantTypes= GrantTypes.Hybrid,
                    IdentityTokenLifetime=3600,
                    //定义这个客户端可以访问的APi资源数组
                    //AllowedScopes=new[]{"testApi" },
                    AllowedScopes=new[]{"testApi",IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile,"TestResource" },
                    //允许将Token通过浏览器传递
                    AllowAccessTokensViaBrowser=true
                },

            };
        }

        /// <summary>
        /// 哪些User可以被这个AuthorizationServer识别并授权
        /// </summary>
        /// <returns></returns>
        public static List<TestUser> GetTestUsers()
        {
            return new List<TestUser>
            {
               new TestUser
               {
                   SubjectId="111",
                   Username="zx",
                   Password="123456",
                   IsActive=true,
                   Claims=new List<Claim> {
                       new Claim(IdentityModel.JwtClaimTypes.Role,"User"),
                       new Claim("Claim1","ClaimValue1"),
                       new Claim("Claim2","ClaimValue2"),
                       new Claim("Claim3","ClaimValue3"),

                   }
               }
           };
        }


    }

public class ProfileService : IProfileService
    {
        protected readonly TestUserStore Users;
        public ProfileService(TestUserStore users)
        {
            Users = users;
        }
        public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var user = Users.FindBySubjectId(context.Subject.GetSubjectId());
            if (user != null)
            {
                //context.IssuedClaims = user.Claims.ToList();
                context.IssuedClaims.AddRange(user.Claims);
            }

            return Task.CompletedTask;
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            await Task.Run(() =>
            {
                context.IsActive = true;
            });
        }
    }

准备完毕后在程序包管理器控制台执行如下命令

EntityFrameworkCore\Add-Migration ConfigDbContext -c ConfigurationDbContext  -o Data/Migrations/IdentityServer/PersistedGrantDb



EntityFrameworkCore\Update-Database -context ConfigurationDbContext



EntityFrameworkCore\Add-Migration  OperationContext -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/OperationDb



EntityFrameworkCore\Update-Database -context PersistedGrantDbContext

方法二: 使用官方包 MySql.Data.EntityFrameworkCore 失败了


注意事项:

需要在MySQL 先执行创建CodeFirst记录表

CREATE TABLE `__EFMigrationsHistory` (
  `MigrationId` varchar(150) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `ProductVersion` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`MigrationId`)
) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值