Skip to main content

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.

Identity Server 4 là gì?

IdentityServer4 là 1 framework  .NET dành cho OpenID Connect và OAuth 2.0. Ngoài ra, bạn có thể tìm 1 số thư viện khác dành cho .net core.
Hiện tại, mình chỉ biết 1 vài thư viện làm nhiệm vụ như Authorization Server:
  1. Identity Server 4
  2. Azure Active Directory
  3. Auth0
  4. OpenIddict
  5. Google OAuth 2.0
  6. Facebook Login
Trước khi bắt đầu, các bạn cần đảm bảo đang sử dụng Visual Studio 2017, .Net Core 1.1.
Mình đã thử sử dụng .Net Core 2.0 Preview, thì thấy code khác rất nhiều, cả về SDK lẫn các hàm trong IdentityServer 4.

Khai báo Identity Server 4

Tạo Project .NET Core mới, chọn Empty/Web API. Mình khuyến khích các bạn chọn Empty Project vì chúng ta dùng host này để tạo access token, validate token, … Còn 1 số api khác sẽ được viết trong Project Web API.
Trong ví dụ dưới dây, mình sẽ chọn Project Web API, vì template project đã có khai báo 1 số thư viện, hàm sẵn, không cần thêm lại như Empty Project.
Port sử dụng là 60361. Đây là project xây dựng Authorization Server.

Mặc định, Project Web API sẽ không có Authentication cho project Web API.

Cài đặt Identiy Server 4

Install-Package IdentityServer4
Trong file Startup.cs, bạn đăng ký dependency cho IdentityServer4 trong hàm ConfigureServices và sử dụng nó trong hàm Configure
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
 services.AddIdentityServer()
  .AddInMemoryClients(new List<Client>())
  .AddInMemoryIdentityResources(new List<IdentityResource>())
  .AddInMemoryApiResources(new List<ApiResource>())
  .AddTestUsers(new List<TestUser>())
  .AddTemporarySigningCredential();
 // Add framework services.
 //…
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
 //log factory

 app.UseIdentityServer();
 app.UseStatusCodePages();
 //another code here
}
Sau khi cấu hình xong, các bạn có thể xem OpenID Connect Discovery Document tại: /.well-known/openid-configuration

Định nghĩa Clients, Resources, và Users

Đầu tiên chúng ta cần lưu trữ các ứng dụng Client được phép sử dụng IdentityServer, Resource, và User cho phép xác thực chúng.
Để đơn giản, chúng ta sẽ sử dụng đối tượng trên Memory thay vì sử dụng chúng trên database
internal class Clients
{
 public static IEnumerable<Client> Get()
 {
  return new List<Client> {
   new Client {
    ClientId = "oauthClient",
    ClientName = "Example Client Credentials Client Application",
    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
    ClientSecrets = new List<Secret> {
     new Secret("superSecretPassword".Sha256())},
    AllowedScopes = new List<string> {"customAPI.read"}
   }
  };
 }
}
internal class Resources
{
 public static IEnumerable<IdentityResource> GetIdentityResources()
 {
  return new List<IdentityResource> {
   new IdentityResources.OpenId(),
   new IdentityResources.Profile(),
   new IdentityResources.Email(),
   new IdentityResource {
    Name = "role",
    UserClaims = new List<string> {"role"}
   }
  };
 }

 public static IEnumerable<ApiResource> GetApiResources()
 {
  return new List<ApiResource> {
   new ApiResource {
    Name = "customAPI",
    DisplayName = "Custom API",
    Description = "Custom API Access",
    UserClaims = new List<string> {"role"},
    ApiSecrets = new List<Secret> {new Secret("scopeSecret".Sha256())},
    Scopes = new List<Scope> {
     new Scope("customAPI.read"),
     new Scope("customAPI.write")
    }
   }
  };
 }
}
internal class Users
{
 public static List<TestUser> Get()
 {
  return new List<TestUser> {
   new TestUser {
    SubjectId = "5BE86359-073C-434B-AD2D-A3932222DABE",
    Username = "anbinhtrong",
    Password = "password123",
    Claims = new List<Claim> {
     new Claim(JwtClaimTypes.Email, "anbinhtrong@gmail.com"),
     new Claim(JwtClaimTypes.Role, "admin")
    }
   }
  };
 }
}
Cập nhật lại file Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
 //add Identity Server
 services.AddIdentityServer()
  .AddInMemoryClients(Clients.Get())
  .AddInMemoryIdentityResources(Configurations.Resources.GetIdentityResources())
  .AddInMemoryApiResources(Configurations.Resources.GetApiResources())
  .AddTestUsers(Users.Get())
  .AddTemporarySigningCredential();
 // Add framework services.
 services.AddMvc();
}
Sau khi cài đặt xong, bạn mở trình duyệt gõ địa chỉ: http://localhost:60361/.well-known/openid-configuration

Trang này để lấy thông tin metadata của IdentityServer: scope, issuer name, key material, ..

Test IdentityServer 4

Bạn dùng PostMan hoặc Fiddler để đăng nhập lấy token.
Đối với trường hợp bạn dùng grant_type=password, thì contype-header phải là application/x-www-form-urlencoded.
 
Trường hợp bạn dùng Fiddler:




Content-type: application/x-www-form-urlencoded
RequestBody:
client_id=oauthClient&client_secret=superSecretPassword&grant_type=password&username=anbinhtrong&password=password123&scope=customAPI.read
Nếu request thành công, bạn sẽ nhận về được chuỗi token giống như sau:


Download example:  MediaFire

Tham khảo

https://www.scottbrady91.com/Identity-Server/Getting-Started-with-IdentityServer-4
Identity Server 4 Sample: https://github.com/IdentityServer/IdentityServer4.Samples

Chúc các bạn thành công! 
Nhatkyhoctap's blog

Comments

  1. OAuth2 có 4 loại grant type:
    - Resource Owner Password Credentials
    - Authorization Code
    - Implicit
    - Client Credentials
    The Password grant type is a way to exchange a user's credentials for an access token.
    Khi nào thì sử dụng grant này?
    Chỉ nên sử dụng cho những ứng dụng thực sự được tin tưởng vì nó trực tiếp xử lý thông tin đăng nhập của người dùng.
    The flow includes the following steps:
    Ứng dụng đưa ra một form cho phép người dùng nhập thông tin đăng nhập (ví dụ: username/password).
    Ứng dụng gửi thông tin đăng nhập cùng thông tin định danh của mình lên authorization server. Authorization server xác thực thông tin, trả lại access token và refresh token (nếu có).
    Ứng dụng sử dụng access token truy cập tài nguyên trên resource server.

    ReplyDelete

Post a Comment

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.

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