identityserver4 - 更新 IdentityServer4 的客户端数据库

标签 identityserver4

我在我的网络核心应用程序中将identityServer4作为我的oAuth服务器。我能够使用以下代码初始化我的客户端数据库:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                SeedData.EnsureSeedData(serviceScope);
            }
        } 
    }

迁移和客户端初始化是使用

完成的
  public class SeedData
{
    public static void EnsureSeedData(IServiceScope serviceScope)
    {
        Console.WriteLine("Seeding database...");

           serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

            var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
            context.Database.Migrate();

            EnsureSeedData(context);

        Console.WriteLine("Done seeding database.");
        Console.WriteLine();
    }

    private static void EnsureSeedData(ConfigurationDbContext context)
    {
        if (!context.Clients.Any())
        {
            Console.WriteLine("Clients being populated");
            foreach (var client in Config.GetClients().ToList())
            {
                context.Clients.Add(client.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
           Console.WriteLine("Clients already populated, update clients");
                foreach (var client in Config.GetClients().ToList())
                {
                    var item = context.Clients.Where(c => c.ClientId == client.ClientId).FirstOrDefault();
                   if(item == null)
                    {
                        context.Clients.Add(client.ToEntity());
                    } else {
                        var model = client.ToEntity();
                        model.Id = item.Id;
                        context.Entry(item).CurrentValues.SetValues(model);
                    }                       
                }
                context.SaveChanges();
            }

            if (!context.IdentityResources.Any())
        {
            Console.WriteLine("IdentityResources being populated");
            foreach (var resource in Config.GetIdentityResources().ToList())
            {
                context.IdentityResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
           Console.WriteLine("IdentityResources already populated");
                foreach (var resource in Config.GetIdentityResources().ToList())
                {
                    var item = context.IdentityResources.Where(c => c.Name == resource.Name).FirstOrDefault();
                    if (item == null)
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }
                    else
                    {
                        var model = resource.ToEntity();
                        model.Id = item.Id;
                        context.Entry(item).CurrentValues.SetValues(model);
                    }
                }
                context.SaveChanges();
            }

            if (!context.ApiResources.Any())
        {
            Console.WriteLine("ApiResources being populated");
            foreach (var resource in Config.GetApiResources().ToList())
            {
                context.ApiResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
           Console.WriteLine("ApiResources already populated");
                foreach (var resource in Config.GetApiResources().ToList())
                {
                    var item = context.ApiResources.Where(c => c.Name == resource.Name).FirstOrDefault();
                    if (item == null)
                    {
                        context.ApiResources.Add(resource.ToEntity());
                    }
                    else
                    {
                    var model = resource.ToEntity();
                    model.Id = item.Id;
                    context.Entry(item).CurrentValues.SetValues(model);
                    }
                }
               context.SaveChanges();
            }
    }
}

客户端数据库的初始化工作正常。然而,更新客户端数据库存在问题。部分记录未更新。有更好的方法吗?

最佳答案

经过一番努力,我找到了一个适合我的解决方案。基本上,我创建了一个表 ClientVersion,用于跟踪客户端定义更改。

这是我的新版本的 SeedData.cs。

   public class SeedData
{
    public static void EnsureSeedData(IServiceScope serviceScope)
    {
        Console.WriteLine("Seeding database...");

        serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();

        var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
        context.Database.Migrate();

        var versionContext = serviceScope.ServiceProvider.GetRequiredService<VersionContext>();
        versionContext.Database.Migrate();

        EnsureSeedData(context, versionContext);

        Console.WriteLine("Done seeding database.");
        Console.WriteLine();
    }

    private static void EnsureSeedData(ConfigurationDbContext context, VersionContext versionContext)
    {
        ClientVersion version = versionContext.ClientVersion.FirstOrDefault();
        bool blUpdate = version == null ? true : (Config.CurrentVersion > version.Version ? true: false);
        if(blUpdate)
        {
            if(version == null)
            {
                version = new ClientVersion()
                {
                    Version = Config.CurrentVersion,
                };
                versionContext.ClientVersion.Add(version);
            } else
            {
                version.Version = Config.CurrentVersion;
                versionContext.ClientVersion.Update(version);
            }
            versionContext.SaveChanges();
        }
        if (!context.Clients.Any())
        {
            Console.WriteLine("Clients being populated");
            foreach (var client in Config.GetClients().ToList())
            {
                context.Clients.Add(client.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
            Console.WriteLine("Clients already populated, update clients");
            if (blUpdate)
            {
                foreach (var client in Config.GetClients().ToList())
                {
                    var item = context.Clients
                        .Include(x => x.RedirectUris)
                        .Include(x => x.PostLogoutRedirectUris)
                        .Include(x => x.ClientSecrets)
                        .Include(x => x.Claims)
                        .Include(x => x.AllowedScopes)
                        .Include(x => x.AllowedCorsOrigins)
                        .Include(x => x.AllowedGrantTypes)
                        .Where(c => c.ClientId == client.ClientId).FirstOrDefault();
                    if (item != null)
                    {
                        context.Clients.Remove(item);
                    }
                    context.Clients.Add(client.ToEntity());
                }
                context.SaveChanges();
            }
        }

        if (!context.IdentityResources.Any())
        {
            Console.WriteLine("IdentityResources being populated");
            foreach (var resource in Config.GetIdentityResources().ToList())
            {
                context.IdentityResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
            Console.WriteLine("IdentityResources already populated");
            if (blUpdate)
            {
                foreach (var resource in Config.GetIdentityResources().ToList())
                {
                    var item = context.IdentityResources.Where(c => c.Name == resource.Name).FirstOrDefault();
                    if (item != null)
                    {
                        context.IdentityResources.Remove(item);
                    }
                    context.IdentityResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }
        }

        if (!context.ApiResources.Any())
        {
            Console.WriteLine("ApiResources being populated");
            foreach (var resource in Config.GetApiResources().ToList())
            {
                context.ApiResources.Add(resource.ToEntity());
            }
            context.SaveChanges();
        }
        else
        {
            Console.WriteLine("ApiResources already populated");
            if (blUpdate)
            {
                foreach (var resource in Config.GetApiResources().ToList())
                {
                    var item = context.ApiResources.Where(c => c.Name == resource.Name).FirstOrDefault();
                    if (item != null)
                    {
                        context.ApiResources.Remove(item);
                    }
                    context.ApiResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }
        }
    }
}

关于identityserver4 - 更新 IdentityServer4 的客户端数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49888019/

相关文章:

c# - 无法在 ASP.NET Core 2 应用程序上注销 identityserver4 的 OpenIdConnect 身份验证

access-token - 身份服务器 4 中的静默 token 更新,js 客户端应用程序未按预期工作

cookies - 未在 iframe 中设置 Cookie

azure-service-fabric - Azure 服务结构 : Make endpoint Input and Internal for identity server 4

.net-core - 使用 safari 和 Identity Server 4 登录时出现问题

angular - 调用 signinRedirect 时 Oidc-client 无限循环

c# - 自定义 API Controller 总是返回 404 not found

c# - IdentityServer4 30 分钟后自动注销

c# - 如何在 IdentityServer4 中向访问 token 添加自定义声明?

c# - 为什么 IdentityServer4 ApiResource 不能与 JwtBearerOption.Audience 一起使用?