Skip to main content

Identity Server 4: Sử dụng EntityFramework Core cho Configuration data (Part 5)

Trong bài viết này, mình sẽ hướng dẫn các bạn sử dụng Entity Framework để lưu trữ các thiết lập của IdentityServer 4 vào database.
Có 2 loại dữ liệu cần được lưu trữ vào database:
  1. Configuration data: resource và client (Configuration Store)
  2. Operation data: là loại dữ liệu phát sinh trong quá trình sử dụng Identity Server (token, code và consent). (Persisted Stored)

Bạn cài đặt 2 package IdentityServer4.EntityFramework cho project
  1. IdentityServer4Demo.IdentityServer4.EntityFramework
  2. Microsoft.EntityFrameworkCore.SqlServer

Nhấp phải file IdentityServer4Demo.csprj, chọn Edit, bạn thêm dòng này vào trong thẻ ItemGroup
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />

Thiết lập Store để lưu dữ liệu

Configuration Store cho phép lưu trữ các thiết lập từ các lớp thực thi cho các interface: IClientStore, IResourceStore, và ICorsPolicyService.
Để sử dụng Configuration Store, bạn sử dụng hàm AddConfigurationStore.
services.AddIdentityServer()
// this adds the config data from DB (clients, resources, CORS)
.AddConfigurationStore(options =>
{
 options.ConfigureDbContext = builder =>
  builder.UseSqlServer(connectionString,
   sql => sql.MigrationsAssembly(migrationsAssembly));
});
Persisted grant store dùng để lưu trữ tất cả thông tin authorization grants, consents, và tokens.
services.AddIdentityServer()
// this adds the operational data from DB (codes, tokens, consents)
.AddOperationalStore(options =>
{
 options.ConfigureDbContext = builder =>
  builder.UseSqlServer(connectionString,
   sql => sql.MigrationsAssembly(migrationsAssembly));

 // this enables automatic token cleanup. this is optional.
 options.EnableTokenCleanup = true;
 options.TokenCleanupInterval = 30; // interval in seconds
Chú ý là những hàm sau đây được thay bằng AddConfigurationStore and AddOperationalStore.
AddInMemoryPersistedGrants
AddInMemoryIdentityResources
AddInMemoryApiResources
AddInMemoryClients
Kết hợp đoạn code chứa Configuration Store và Persisted grant Store, ta có đoạn code sau:
//add Identity Server
services.AddIdentityServer()
 //.AddTemporarySigningCredential()
 .AddSigningCredential(cert)
 // this adds the config data from DB (clients, resources)
 .AddConfigurationStore(options =>
 {
  options.ConfigureDbContext = builder =>
   builder.UseSqlServer(connectionString,
    sql => sql.MigrationsAssembly(migrationsAssembly));
 })
 // this adds the operational data from DB (codes, tokens, consents)
 .AddOperationalStore(options =>
 {
  options.ConfigureDbContext = builder =>
   builder.UseSqlServer(connectionString,
    sql => sql.MigrationsAssembly(migrationsAssembly));

  // this enables automatic token cleanup. this is optional.
  options.EnableTokenCleanup = true;
  options.TokenCleanupInterval = 30;
 })
 .AddTestUsers(Users.Get());

Thêm Migrations

Để tạo migrations, bạn mở cmd, và thực hiện 2 lệnh sau:
 
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
Các migrations sẽ được tạo trong folder ~/Data/Migrations/IdentityServer

Khởi tạo Database

Thay vì sử dụng Clients, IdentityResources, và ApiResources từ memory, bạn sẽ lưu data vào ConfigurationStore và sử dụng chúng từ database.
Trong file Startup.cs, bạn thêm hàm InitializeDatabase
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 Clients.Get())
   {
    context.Clients.Add(client.ToEntity());
   }
   context.SaveChanges();
  }

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

  if (!context.ApiResources.Any())
  {
   foreach (var resource in Resources.GetApiResources())
   {
    context.ApiResources.Add(resource.ToEntity());
   }
   context.SaveChanges();
  }
 }
}
Bạn gọi hàm InitializeDatabase trong hàm Configure().
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // this will do the initial DB population
    InitializeDatabase(app);

    // the rest of the code that was already here
    // ...
}
Bạn run project IdentityServer4Demo, database sẽ được tạo cùng với configuration data.

Bạn thực hiện đăng nhập để kiểm tra lại kết quả.
Download Example: http://www.mediafire.com/file/jxkmxqwkyd0twj3
Chúc các bạn thành công.

Comments

Popular posts from this blog

Lập trình đa luồng với Task

Bài viết được đăng trên Jou Lập trình
Trong phiên bản .NET framework 4.0, Microsoft đã bổ sung nhiều thư viện hỗ trợ việc xử lý đa luồng (multi-threading), nhằm đơn giản hóa việc lập trình lẫn hiệu suất của chương trình. Trong bài viết này, tôi xin hướng dẫn các bạn sử dụng lớp System.Threading.Task.

Tìm hiểu về IdentityServer 4

Trong bài viết này, mình sẽ hướng dẫn các bạn làm quen với thư viện Identity Server 4, và tích hợp các service In-Memory của Identity Server 4 vào Project Web API trong .NET Core.

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize
Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh.
Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.