Tài liệu thực hành ASP NET Core Web API IT Research Department BKAP 2022 Page | 1 JWT Authentication in ASP NET Core Web API Mục tiêu ● Tạo database Hanam88Service ● Tạo ứng dụng ASP NET Core Web API.
Trang 1IT Research Department @BKAP 2022 Page | 1
JWT Authentication in ASP.NET Core Web API
Mục tiêu
● Tạo database Hanam88Service
● Tạo ứng dụng ASP.NET Core Web API
● Sử dung Entity Framework (Database First)
● Cấu hình JWT
● Login và sinh Token
● Cấu hình Authorize vào ProductController
● Test với Postman
Step 1: Mở SQL Server 2012 hoặc cao hơn và chạy đoạn kịch bản dưới đây để tạo
cơ sở dữ liệu
go
use Hanam88Service
go
-TẠO BẢNG LOẠI SẢN
(
CategoryId int identity primary key,
CategoryName nvarchar(200)
)
go
-dữ
liệu -insert into Category values(N'Kính')
insert into Category values(N'Ví da')
insert into Category values(N'Giầy Dép')
go
-TẠO BẢNG SẢN
(
ProductId varchar(16) primary key,
ProductName nvarchar(128),
CategoryId int foreign key references Category(CategoryId) null,
Picture nvarchar(512),
Price float,
Note nvarchar(max)
)
go
Trang 2IT Research Department @BKAP 2022 Page | 2
(
AccountId varchar(36) primary key,
Username varchar(32),
Password varchar(256),
Email varchar(128),
FullName nvarchar(64)
)
go
insert into Account values(NEWID(),'hanam88',lower(CONVERT(VARCHAR(32), HashBytes('md5', '123456'), 2)),'hanam88.congdong@gmail.com','Charles Chung')
insert into Product values('AN001',N'Áo sơ mi', ,'',120000,N'');
insert into Product values('BN002',N'Bộ đồ công sở trắng', ,'',140000,N'');
insert into Product values('BN003',N'Bộ đồ công sở kẻ caro', ,'',80000,N'');
insert into Product values('DN334',N'Đầm Bbd Thuỷ Thủ 334', ,'',160000,N'');
insert into Product values('DN332',N'Đầm Bbd Thuỷ Thủ 332', ,'',180000,N'');
insert into Product values('QJ119',N'Quần Jean Dài Nữ 13 ( 119)', ,'',180000,N'');
insert into Product values('AC331',N'Set Caro 331', ,'',190000,N'');
54', ,'',120000,N'');
insert into Product values('QD296',N'Quần Dài Đen + Áo Voan 296', ,'',145000,N'');
insert into Product values('SM449',N'Sơ Mi Chấm Bi Khoét Vai 449', ,'',85000,N'');
009', ,'',65000,N'');
insert into Product values('VN001',N'Ví forever young đa di năng', ,'',65000,N'');
TV103', ,'',500000,N'');
Thương Hiệu Chính Hãng Banyanu', ,'',185000,N'');
Step 2: Mở Visual Studio 2017 -> Tạo ứng dụng ASP.NET Core Web Application
Trang 3IT Research Department @BKAP 2022 Page | 3
- Chọn các thông số như hình dưới và nhận OK
Trang 4
IT Research Department @BKAP 2022 Page | 4
Step 3: Tạo thư mục Models trong Project
Step 4: Vào menu Tools -> NuGet Package Manager -> Package Manager Console và gõ
lệnh như hình và nhấn Enter để kết nối database và sinh ra các Entity và DbContext
Step 5: Mở tệp Hanam88ServiceContext.cs trong thư mục Models và xóa đoạn code như
hình dưới đi
Step 6: Mở tệp appsettings.json và nhập các thông số cấu hình như sau
Trang 5IT Research Department @BKAP 2022 Page | 5
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Hanam88ConnectSQL":
"Server=localhost;database=Hanam88WebAPI;uid=sa;pwd=1234$;MultipleActiveResultSets=Tr ue"
},
"Jwt": {
"Issuer": "hanam88.com",
"Audience": "sinhvienbkap",
"Key": "demo_jwt_security_for_sinhvienbkap"
}
}
Step 7: Mở tệp Startup.cs tìm phương thức ConfigureServices bổ sung code cấu hình khi
ứng dụng khởi động như sau
//lấy key trong tệp cấu hình
var key = Configuration["Jwt:Key"];
//mã hóa key
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); //Add Authentication Bearer
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters {
//có kiểm tra Issuer (default true)
ValidateIssuer = true,
ValidIssuer = Configuration["Jwt:Issuer"],
//có kiểm tra Audience (default true)
ValidateAudience = true,
ValidAudience = Configuration["Jwt:Audience"],
//Đảm bảo phải có thời gian hết hạn trong token
RequireExpirationTime = true,
ValidateLifetime = true,
//Chỉ ra key sử dụng trong token
IssuerSigningKey = signingKey,
RequireSignedTokens = true
};
});
services.AddDbContext<Hanam88WebAPIContext>(
options =>
options.UseSqlServer(Configuration.GetConnectionString("Hanam88ConnectSQL")));
Tìm phương thức Configure bổ sung dòng sau vào trước lệnh app.UseMvc()
//sử dụng tính năng Authentication
app.UseAuthentication();
Trang 6IT Research Department @BKAP 2022 Page | 6
Step 8: Tạo lớp UserModel trong thư mục Models
{
public string Username { get; set; }
public string Password { get; set; }
}
Step 9: Trong thư mục Controllers xóa tệp ValuesController đi và tạo Controller có tên AccountController và code như sau
[Route("api/[controller]")]
[ApiController]
{
Hanam88WebAPIContext db;
IConfiguration config;
public AccountController(Hanam88WebAPIContext db, IConfiguration config)
{
this.db = db;
this.config = config;
}
[HttpPost("login")]
public IActionResult Login([FromBody] UserModel model)
{
//mã hóa password thành chuỗi MD5
var password_md5 = GenerateMD5(model.Password);
//lấy người dùng trong db
var user = db.Account.FirstOrDefault(x => x.Username == model.Username && x.Password == password_md5);
//nếu tồn tại thì xử lý sing token
if (user != null)
{
//lấy key trong file cấu hình
var key = config["Jwt:Key"];
//mã hóa ky
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); //ký vào key đã mã hóa
var signingCredential = new SigningCredentials(signingKey,
SecurityAlgorithms.HmacSha256);
//tạo claims chứa thông tin người dùng (nếu cần)
var claims = new List<Claim>
{
new Claim(ClaimTypes.Role,"Admin"),
new Claim(ClaimTypes.Name,model.Username),
new Claim(ClaimTypes.MobilePhone,"0961902588"),
new Claim(ClaimTypes.Country,"Vietnam"),
};
//tạo token với các thông số khớp với cấu hình trong startup để validate
var token = new JwtSecurityToken
(
issuer: config["Jwt:Issuer"],
audience: config["Jwt:Audience"],
expires: DateTime.Now.AddHours(1),
signingCredentials: signingCredential,
Trang 7IT Research Department @BKAP 2022 Page | 7
claims: claims
);
//sinh ra chuỗi token với các thông số ở trên
var hanam88token = new JwtSecurityTokenHandler().WriteToken(token); //trả về kết quả cho client username và chuỗi token
return new JsonResult(new { username = model.Username, token =
hanam88token });
}
//trả về lỗi
return new JsonResult(new { message = "Đăng nhập sai" });
}
//hàm mã hóa 1 chuỗi sử dụng MD5
private string GenerateMD5(string input)
{
// Step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
//lấy thông tin trong claims sau khi login
[Authorize]
[HttpGet("GetClaim")]
public IActionResult GetClaims()
{
var claims = from c in User.Claims
select new {Type=c.Type.Substring(c.Type.LastIndexOf("/")+1), c.Value };
return new JsonResult(claims);
}
[Authorize(Roles ="admin")]
[HttpGet("GetAccount")]
public IActionResult GetAccount()
{
return new JsonResult(new { message = "Xin chào Admin" });
}
}
Step 10: Trong thư mục Controllers tạo Controller có tên ProductController và
code như sau
[Route("api/[controller]")]
[ApiController]
[Authorize]
{
//khai báo đối tượng context
Hanam88WebAPIContext db;
//phương thức constructor khởi tạo context
Trang 8IT Research Department @BKAP 2022 Page | 8
//(do chúng ta đã cấu hình trong startup nên asp.net core sẽ tự khởi tạo
DbContext và nhận qua constructor)
//tìm hiểu dependency inject trong net nhé
public ProductController(Hanam88WebAPIContext db)
{
this.db = db;
}
public IActionResult GetProducts()
{
return new JsonResult(db.Product);
}
}
Step 11: Cài công cụ postman lên để test nhé
- Test UnAuthorize
- Login để lấy token
Trang 9IT Research Department @BKAP 2022 Page | 9
Nhập thông tin sai nhé
Nhập thông tin đúng
Trang 10IT Research Department @BKAP 2022 Page | 10
- Test gửi Token để truy cập tài nguyên hạn chế (Protected Resource)
THE END