

Xác thực thông qua Token trong ứng dụng Web sử dụng .NET Core
- 30-06-2025
- Toanngo92
- 0 Comments
Mục lục
12.1 Tổng quan
Khi phát triển một ứng dụng web, vấn đề bảo mật luôn là một phần quan trọng trong quá trình phát triển. Trước đây, việc bảo mật trong ứng dụng web được quản lý bằng cách lưu thông tin trong phiên làm việc (session) hoặc sử dụng xác thực dựa trên form (.NET Forms-Based Authentication) như minh họa trong Hình 12.1.
🖼 Hình 12.1: Lưu trữ dữ liệu trong Session

Tuy nhiên, việc lưu dữ liệu xác thực trong session gây ra nhiều rắc rối như làm tăng độ phức tạp và khó quản lý. Vấn đề này được khắc phục bằng việc sử dụng dịch vụ lưu trữ đám mây (cloud services).
12.2 Xác thực dựa trên Token (Token-Based Authentication)
Mô hình Cloud + SPA:
Trong môi trường điện toán đám mây và các ứng dụng web dạng SPA (Single Page Application), client sẽ thường xuyên gọi các RESTful Web API hoặc controller ASP.NET MVC để lấy hoặc gửi dữ liệu, như minh họa trong Hình 12.2. Điều này đảm bảo rằng logic xử lý nghiệp vụ được chuyển hoàn toàn về phía client.
🖼 Hình 12.2: Lưu trữ dữ liệu trong môi trường đám mây và SPA

Token-Based Authentication là gì?
- Xác thực là quá trình xác minh danh tính người dùng trước khi cấp quyền truy cập vào ứng dụng, module, file hoặc dữ liệu cụ thể.
- Token-based authentication bổ sung một bước xác thực mã hóa trong toàn bộ quá trình.
- Khi người dùng đăng nhập thành công (thường thông qua username và password), một token (mã thông báo) sẽ được tạo ra để đại diện cho quyền truy cập.
- Token này được sử dụng cho các request tiếp theo – tránh yêu cầu đăng nhập lại.
- Nếu token hết hạn hoặc không hợp lệ, yêu cầu sẽ bị từ chối.
Đặc điểm:
- Token-based authentication rất an toàn và khó bị tấn công.
- Được sử dụng rộng rãi trong các ứng dụng mobile, SPA và dịch vụ Web API.
- Dạng phổ biến nhất là JSON Web Token (JWT).
JWT là gì?
- Là một chuẩn mở (open standard) để truyền thông tin một cách an toàn giữa các bên.
- Có thể dùng trong ASP.NET, Python, Java hoặc các công nghệ backend khác.
- Dữ liệu được truyền qua URL, trong phần HTTP header hoặc HTTP POST body.
Cấu trúc của JWT:
JWT là chuỗi JSON gồm 3 phần:
- Header – chứa metadata và thuật toán mã hóa
- Payload – chứa thông tin dữ liệu (username, role, v.v.)
- Signature – xác minh tính toàn vẹn của token
Tạo JWT trong ASP.NET Core Web API
Code Snippet 1 – Tạo JWT
var secureKey = new SymmetricSecurityKey(
System.Text.Encoding.UTF8.GetBytes("This is the secured key"));
var credentials = new SigningCredentials(secureKey,
SecurityAlgorithms.HmacSha256);
var claims = new[] {
new Claim(ClaimTypes.Name, user.username),
new Claim(JwtRegisteredClaimNames.Sub, user.username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString("N"))
};
var token = new JwtSecurityToken(
issuer: "Abcd.com",
audience: "Abcd.com",
claims: claims,
expires: DateTime.Now.AddMinutes(60),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
Giải thích chi tiết Code Snippet 1:
- Tạo một khóa đối xứng (SymmetricSecurityKey) để mã hóa JWT.
- Sử dụng
SigningCredentials
để ký JWT với thuật toán HMAC-SHA256. - Thêm
claims
– chứa thông tin người dùng nhưusername
,JTI
,subject
. - Tạo đối tượng
JwtSecurityToken
. - Chuyển JWT sang dạng chuỗi bằng
JwtSecurityTokenHandler
.
Các lớp được dùng trong đoạn code:
Class | Mô tả |
---|---|
JwtSecurityToken | Đại diện cho một chuỗi JWT |
Claims | Đại diện cho thông tin bên trong JWT (ví dụ username) |
JwtSecurityTokenHandler | Xử lý tạo và xác minh JWT |
JwtRegisteredClaimNames | Chứa danh sách các tên thuộc tính chuẩn cho phần claim trong JWT |
📌 Bảng 12.1: Các lớp được sử dụng trong đoạn mã
12.3 Cấu hình xác thực bằng token trong .NET Core
Xác thực bằng token là một phần quan trọng trong bảo mật các ứng dụng web hiện đại. Trong ASP.NET Core, việc cấu hình xác thực bằng JWT gồm nhiều bước để đảm bảo tính bảo mật và hiệu quả.
Các bước thiết lập:
- Mở Visual Studio 2022
- Tạo một project ASP.NET Core Web API mới
- Đặt tên phù hợp và nhấn Create
- Cài đặt các gói NuGet cần thiết:
- Gói chính là:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
📌 Hình 12.3: Cài đặt gói NuGet thông qua Package Manager Console

👉 Nếu bạn muốn mình tiếp tục dịch phần cấu hình xác thực JWT trong Program.cs
, sử dụng middleware xác thực, hoặc viết controller xử lý đăng nhập và xác minh token, chỉ cần gửi tiếp trang, mình sẽ dịch và giải thích từng bước đầy đủ.
Dưới đây là phần dịch tiếp theo và chi tiết đầy đủ cho Session 12: .NET Core Token Authentication in Web Applications
, từ trang cấu hình xác thực JWT đến phát hành và kiểm thử token:
✅ Cấu hình xác thực JWT trong Program.cs
🔹 Code Snippet 2 – Cấu hình trong Program.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// Thêm các dịch vụ vào container
builder.Services.AddControllers();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
// Thay thế thông tin này bằng giá trị thật trong ứng dụng
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://myapi.com",
ValidAudience = "myclientapp",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("mysecretkey123"))
};
});
// Thêm Swagger để kiểm thử API
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Cấu hình pipeline xử lý HTTP
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// Thêm các middleware xác thực và phân quyền
app.UseRouting();
app.UseAuthentication(); // Bắt buộc có nếu dùng token
app.UseAuthorization();
app.MapControllers();
app.Run();
🔍 Giải thích các thành phần trong Code Snippet 2:
- AddControllers()
→ Đăng ký dịch vụ controller theo mô hình MVC để xử lý HTTP request. - AddAuthentication()
→ Cấu hình middleware xác thực (authentication). - AddJwtBearer()
→ Xác định rằng sẽ sử dụng JWT Bearer làm phương thức xác thực chính. - TokenValidationParameters
→ Cấu hình các điều kiện xác thực như:Issuer
(bên phát hành token)Audience
(người nhận hợp lệ)Lifetime
(thời hạn token)IssuerSigningKey
(khóa bí mật để xác minh token)
🔹 Code Snippet 3 – Cấu hình Middleware
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Cấu hình khác
app.UseAuthentication(); // cần thiết để xử lý JWT
app.UseAuthorization(); // để áp dụng phân quyền
// Các middleware khác
}
7. Bảo vệ các Endpoint
Để đảm bảo rằng chỉ người dùng đã xác thực mới có thể truy cập một API cụ thể, ta sử dụng [Authorize]
.
🔹 Code Snippet 4 – Endpoint bảo mật
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class SecureController : ControllerBase
{
[HttpGet]
public IActionResult GetSecureData()
{
return Ok("This is secure data accessible only with a valid token.");
}
[HttpPost]
public IActionResult PostSecureData([FromBody] SecureDataModel data)
{
// Xử lý dữ liệu
return Ok($"Secure data received and processed. Id: {data.Id}");
}
}
🖼 Hình 12.4 minh họa đoạn mã này trong Visual Studio.

8. Phát hành và cấp phát Token
Để phát hành token, ta cần một class dịch vụ để tạo và trả về token cho người dùng sau khi xác thực thành công.
🔹 Code Snippet 5 – Lớp TokenService
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
public class TokenService
{
private readonly string _secretKey;
private readonly string _issuer;
private readonly string _audience;
public TokenService(string secretKey, string issuer, string audience)
{
_secretKey = secretKey;
_issuer = issuer;
_audience = audience;
}
public string GenerateToken(string userId, string userName, string[] roles)
{
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, userId),
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.Role, string.Join(",", roles))
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secretKey));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: _issuer,
audience: _audience,
claims: claims,
expires: DateTime.UtcNow.AddHours(1),
signingCredentials: credentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
🖼 Hình 12.5: Hiển thị lớp TokenService trong IDE

9. Kiểm thử xác thực
Sau khi triển khai API và phát hành token, có thể dùng các công cụ như Postman hoặc curl để kiểm thử bằng cách thêm token vào phần Header.
🔹 Code Snippet 6 – Gửi Token trong Header
Authorization: Bearer <your_generated_token>
🔐 Ghi chú bổ sung:
- Nếu ứng dụng sử dụng một nhà cung cấp xác thực bên thứ ba như Azure AD hoặc OAuth, thì giá trị
Issuer
cần phải khớp với nhà phát hành thực tế. - Trong môi trường sản phẩm, cần triển khai hệ thống xác thực hoàn chỉnh và bảo mật toàn diện hơn, kết hợp với lưu trữ token, xử lý refresh token v.v.
Dưới đây là bản dịch chi tiết đầy đủ (không rút gọn) cho phần tiếp theo của Session 12: .NET Core Token Authentication in Web Applications, từ mục 12.4 đến 12.5.4:
12.4 Xác thực Token trong ASP.NET Core
Các token phải được xác thực sau khi được tạo. Token có thể được xác thực dưới dạng chuỗi vì nó được truyền qua header như là x-api-token
.
12.4.1 Ủy quyền Metadata tự động
Thông tin chi tiết cần thiết để xác thực token có sẵn dưới dạng metadata. Metadata này có thể được lấy từ máy chủ xác thực bằng cách sử dụng middleware JwtBearer. Metadata được truy xuất trong lần đầu tiên. Sau khi JwtBearer
middleware nhận được dữ liệu, nó sẽ cấu hình hệ thống.
Để xác thực token bằng cách sử dụng JwtBearer
, hãy tạo và mở một dự án ASP.NET Core Web API mới trong Visual Studio 2022.
Các bước để xác thực token với JwtBearer:
- Thêm tham chiếu đến JwtBearer bằng gói:
Microsoft.AspNetCore.Authentication.JwtBearer
Bạn có thể thêm bằng Package Manager Console hoặc .NET CLI.
- Cấu hình xác thực trong
Program.cs
:
Trong Program.cs
, cấu hình các dịch vụ và middleware, đặt JwtBearer
làm scheme xác thực mặc định, như trong Code Snippet 7.
🔹 Code Snippet 7:
var builder = WebApplication.CreateBuilder(args);
// Đăng ký các dịch vụ
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// Cấu hình thông số JwtBearer ở đây
});
// Các cấu hình bổ sung...
var app = builder.Build();
// Cấu hình middleware
app.UseAuthentication(); // Bắt buộc để kích hoạt middleware xác thực
app.UseAuthorization();
app.Run();
- Cấu hình Middleware trực tiếp trong
Program.cs
:
🔹 Code Snippet 8:
var app = builder.Build();
// Cấu hình middleware
if (builder.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication(); // Middleware xác thực
app.UseStaticFiles();
app.UseAuthorization();
app.Run();
📝 Giải thích:
Cấu hình này tích hợp JwtBearer
xác thực vào một ứng dụng ASP.NET Core sử dụng mô hình hosting đơn giản hóa từ .NET 6 trở đi.
12.4.2 Xác định TokenValidationParameters
Các tham số xác thực token cũng có thể được cấu hình thủ công như trong Code Snippet 9.
🔹 Code Snippet 9:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
ValidIssuer = "abcd.com",
ValidAudience = "abcd.com",
IssuerSigningKey = new SymmetricSecurityKey(
System.Text.Encoding.UTF8.GetBytes("This is the secured Key"))
};
});
📌 Các tham số sử dụng bao gồm:
ValidateAudience
: kiểm tra người nhận tokenValidateIssuer
: xác minh nhà phát hành tokenRequireExpirationTime
: buộc phải có thời gian hết hạnValidateLifetime
: xác thực hạn dùng tokenClockSkew
: độ lệch thời gian cho phépIssuerSigningKey
: khóa bí mật dùng để xác thực chữ kýValidIssuer
vàValidAudience
: giá trị hợp lệ cho issuer và audience
12.5 Tìm hiểu thêm về JWT
JWT là một yếu tố cốt lõi trong xác thực dựa trên token, đóng vai trò quan trọng trong việc bảo mật và truyền thông tin giữa các bên.
12.5.1 Định nghĩa và Cấu trúc
JWT là một phương tiện truyền thông nhỏ gọn, độc lập, được mã hóa dạng base64, truyền thông tin an toàn giữa hai bên.
12.5.2 Các thành phần của JWT
JWT bao gồm 3 phần chính:
- Header – chứa thông tin về kiểu token và thuật toán ký.
- Payload – chứa các thông tin (claims) về user hoặc quyền hạn.
- Signature – đảm bảo tính toàn vẹn và xác thực nguồn gốc.
🔹 Code Snippet 10 – Header
{
"alg": "HS256",
"typ": "JWT"
}
🔹 Code Snippet 11 – Payload
{
"sub": "1234567890",
"name": "John Doe",
"exp": 1516239022
}
🔐 Signature: được tạo ra bằng cách mã hóa header + payload bằng thuật toán HMAC SHA-256 và secret key.
12.5.3 Tình huống sử dụng JWT trong .NET Core
🔹 Authentication (Xác thực)
- JWT được sử dụng để xác định danh tính người dùng.
- Sau khi đăng nhập thành công, user sẽ nhận được token để sử dụng trong các request sau.
🔹 Authorization (Phân quyền)
- Claims trong JWT được sử dụng để xác định quyền truy cập.
- Có thể áp dụng hạn chế truy cập endpoint dựa trên các vai trò được xác định.
12.5.4 Tích hợp trong .NET Core
ASP.NET Core hỗ trợ JWT thông qua middleware xác thực. Lập trình viên có thể sử dụng gói Microsoft.AspNetCore.Authentication.JwtBearer
để dễ dàng cấu hình xác thực dựa trên token.
.NET Core xử lý xác thực JWT liền mạch bằng cách đảm bảo token được cấp vẫn hợp lệ, chưa hết hạn và được cấp bởi bên thứ ba đáng tin cậy.
Dưới đây là bản dịch đầy đủ, không bỏ sót ý nào của các trang bạn gửi (từ phần 12.5.5 Security Considerations đến hết phần 12.8 Token-Based Authentication in MVC/Web Applications):
12.5.5 Các cân nhắc về bảo mật
Dưới đây là một số cân nhắc bảo mật chính khi sử dụng JWTs:
- Token Expiry (Hết hạn mã thông báo)
JWT thường có một trườngexpiration claim
(exp), đảm bảo rằng ngay cả khi bị chặn, chúng chỉ hợp lệ trong một khoảng thời gian giới hạn. - Secure Transmission (Truyền tải an toàn)
HTTPS là bắt buộc để truyền tải JWTs một cách an toàn, ngăn chặn việc chặn và giả mạo trong quá trình truyền. - Keep Secrets Safe (Giữ bí mật an toàn)
Bảo vệ khóa bí mật dùng để ký JWT để ngăn người dùng trái phép tạo mã thông báo giả.
Bảng 12.2: So sánh JWT và xác thực token trong .NET Core
Khía cạnh | JWT | .NET Core Token Authentication |
---|---|---|
Định nghĩa và mục đích | Phương tiện nhỏ gọn để truyền thông tin | Khung làm việc để xác thực người dùng |
Cấu trúc | Header, Payload, Signature | Thông tin người dùng, xác thực, cấu hình xác thực token |
Header | Dữ liệu về loại token và thuật toán mã hóa | Cấu hình trong Middleware |
Payload | Chứa các claim về người dùng | Chứa thông tin người dùng và xác thực |
Chữ ký | Đảm bảo toàn vẹn của token | Xác thực nguồn gốc token |
Trường hợp sử dụng trong .NET | Xác thực, Ủy quyền | Thực thi kiểm soát truy cập dựa trên vai trò, chính sách và claim |
12.6 Tạo và cấp phát Token
Việc tạo và cấp phát token là những thành phần không thể thiếu trong quy trình xác thực an toàn trong ứng dụng .NET Core. Quy trình này bao gồm việc tạo JWT với thông tin người dùng, các chữ ký mã hóa, nhằm đảm bảo tính toàn vẹn và xác thực của token.
Quy trình bao gồm các bước sau:
- Định nghĩa Claims
Xác định các claim chứa thông tin về người dùng nhưuserId
,role
,permission
.
Ví dụ:sub
,exp
,roles
. - Dịch vụ tạo token
Cài đặt service hoặc class có trách nhiệm tạo token, với các logic cần thiết. - Tích hợp thư viện JWT
Sử dụng thư viện nhưSystem.IdentityModel.Tokens.Jwt
để dễ dàng tạo và xử lý JWT. - Ký token
Ký token bằng khóa đối xứng (symmetric
) để đảm bảo tính toàn vẹn. - Cấp phát token
Khi người dùng đăng nhập thành công, logic xác thực sẽ kích hoạt và trả về token cho client. - Lưu trữ token an toàn
Token cần được lưu trữ an toàn (ví dụ: tronglocalStorage
,sessionStorage
, hoặccookie
an toàn).
Code Snippet 12 – TokenService
Một class TokenService
tạo ra JWT. Các bước:
- Định nghĩa claim:
sub
,username
,roles
,jti
- Ký JWT bằng secret key
- Đặt thời gian hết hạn (30 phút)
- Trả về token đã được mã hóa
Ví dụ sử dụng:
var tokenService = new TokenService("your_secret_key", "your_issuer");
var token = tokenService.GenerateToken("123456", "john_doe", new[] { "admin", "user" });
Console.WriteLine("Generated Token: " + token);
12.7 Tích hợp Token từ nhà cung cấp Identity
Khi xác thực ứng dụng .NET Core, có thể sử dụng token từ các nhà cung cấp bên thứ ba như Google, Facebook, Azure AD, Okta.
Bước thực hiện:
- Chọn nhà cung cấp (OAuth 2.0 hoặc OpenID Connect)
- Lấy
Client ID
vàSecret
- Cài đặt gói NuGet như
Microsoft.AspNetCore.Authentication.OpenIdConnect
- Cấu hình trong
Program.cs
Ví dụ cấu hình:
services.AddAuthentication(options => {
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options => {
options.Authority = "https://your-identity-provider.com";
options.ClientId = "your-client-id";
options.ClientSecret = "your-client-secret";
options.CallbackPath = "/signin-oidc";
});
Xử lý Callbacks và truy xuất Token:
[HttpGet("/signin-oidc")]
public IActionResult SignInCallback() {
return View("SignInCallback");
}
Lấy Access Token:
var accessToken = await HttpContext.GetTokenAsync("access_token");
Truy xuất thông tin người dùng:
var user = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
Thêm token vào API request:
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", accessToken);
12.8 Xác thực dựa trên Token trong MVC/Web Applications
Hiểu về Token-Based Authentication
- Stateless (Không trạng thái): Không lưu session phía server.
- Mỗi request kèm token xác minh danh tính người dùng.
- Token chứa thông tin định danh:
id
,roles
,exp
, v.v.
Các thành phần của Token
- Header: Loại token & thuật toán mã hóa
- Payload: Dữ liệu (claims) như tên, role
- Signature: Đảm bảo toàn vẹn token bằng thuật toán và khóa bí mật
Quy trình tạo token trong MVC
- Sau khi đăng nhập thành công, server tạo token chứa thông tin định danh người dùng
- Token được ký bằng khóa bí mật và trả về client
Lưu trữ token
- Lưu tại
cookie
,localStorage
,sessionStorage
, hoặc trên app mobile
Xác thực và Ủy quyền
- Middleware đọc token và xác thực
- [Authorize] được dùng để giới hạn quyền truy cập đến controller/action cụ thể
Đăng xuất và Thu hồi Token
- Cần thiết kế cơ chế thu hồi token khi người dùng đăng xuất hoặc tài khoản bị khóa
Lợi ích của xác thực dựa trên Token
- Không cần lưu session phía server
- Hỗ trợ xác thực giữa nhiều hệ thống (cross-domain authentication)
Truyền tải an toàn
- Phải sử dụng HTTPS để mã hóa dữ liệu giữa client và server khi truyền token
Bài tập
Bài tập:
