Chuyển đến nội dung chính

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. 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.

Nhận xét

Bài đăng phổ biến từ blog này

[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.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.