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

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

Nhận xét

  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.

    Trả lờiXóa
  2. Update
    Identity Server 4: Add new scope when you want to registering ID4
    https://docs.identityserver.io/en/latest/reference/api_scope.html

    Trả lờiXóa
  3. https://techmaster.vn/posts/33959/khai-niem-ve-json-web-token
    Phần payload giảng rất rõ về issue

    Trả lờiXóa
  4. As it turns out, my suspicions were right. The audience aud claim in a JWT is meant to refer to the Resource Servers that should accept the token.

    As this post simply puts it:

    The audience of a token is the intended recipient of the token.

    The audience value is a string -- typically, the base address of the resource being accessed, such as https://contoso.com.

    The client_id in OAuth refers to the client application that will be requesting resources from the Resource Server.

    The Client app (e.g. your iOS app) will request a JWT from your Authentication Server. In doing so, it passes it's client_id and client_secret along with any user credentials that may be required. The Authorization Server validates the client using the client_id and client_secret and returns a JWT.

    The JWT will contain an aud claim that specifies which Resource Servers the JWT is valid for. If the aud contains www.myfunwebapp.com, but the client app tries to use the JWT on www.supersecretwebapp.com, then access will be denied because that Resource Server will see that the JWT was not meant for it.

    Trả lờiXóa

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