ASP.NET Core full auth setup reference note
Full auth setup — backend reference
ASP.NET Core Identity + JWT Bearer। যেকোনো নতুন প্রজেক্টে এই ফ্লো follow করলেই হবে।
IdentityDbContext→
Migration→
Program.cs config→
TokenService→
Seed data→
AuthController→
Authorize
একবারই
▼
প্রজেক্টে শুরুতেই এই দুটো প্যাকেজ ইনস্টল করতে হবে। Identity এবং JWT দুটোই লাগবে।
Microsoft.AspNetCore.Authentication.JwtBearer
NuGet Package Manager বা terminal থেকে dotnet add package <name> দিয়ে করা যাবে।
একবারই
▼
DbContext এর বদলে IdentityDbContext inherit করাতে হবে। এতেই AspNetUsers, AspNetRoles সব টেবিল auto তৈরি হয়।
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options)
: base(options) { }
// তোমার নিজের টেবিলগুলো এখানে
public DbSet<BlogPost> BlogPosts { get; set; }
public DbSet<Category> Categories { get; set; }
}
terminal
▼
IdentityDbContext যোগ করার পর migration দিতে হবে। এতে Identity এর সব টেবিল DB তে চলে আসবে।
dotnet ef database update
DB তে AspNetUsers, AspNetRoles, AspNetUserRoles, AspNetUserClaims ইত্যাদি টেবিল তৈরি হবে।
গুরুত্বপূর্ণ
▼
তিনটি কাজ করতে হবে এখানে — Identity register, JWT Authentication configure, এবং pipeline এ যোগ করা।
// ১. Identity
builder.Services.AddIdentityCore<IdentityUser>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
})
.AddRoles<IdentityRole>()
.AddTokenProvider<DataProtectorTokenProvider<IdentityUser>>("Blog")
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// ২. JWT Authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
// ৩. TokenService register
builder.Services.AddScoped<ITokenService, TokenService>();
app.UseAuthentication(); app.UseAuthorization();
"Jwt": {
"Key": "A_Very_Secret_Key_That_Is_At_Least_32_Characters_Long",
"Issuer": "https://localhost:7071",
"Audience": "https://localhost:7071"
}
Key অবশ্যই ৩২+ character হতে হবে, নাহলে runtime error আসবে।
গুরুত্বপূর্ণ
▼
এটাই “টোকেন ফ্যাক্টরি”। Claims তৈরি করে, secret key দিয়ে sign করে, string হিসেবে return করে।
public interface ITokenService
{
string CreateJwtToken(IdentityUser user, List<string> roles);
}
public class TokenService : ITokenService
{
private readonly IConfiguration configuration;
public TokenService(IConfiguration configuration)
{
this.configuration = configuration;
}
public string CreateJwtToken(IdentityUser user, List<string> roles)
{
// ১. Claims — টোকেনে কী তথ্য থাকবে
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, user.Email)
};
foreach (var role in roles)
claims.Add(new Claim(ClaimTypes.Role, role));
// ২. Secret key
var key = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(configuration["Jwt:Key"]));
// ৩. Signing credentials (algorithm)
var credentials = new SigningCredentials(
key, SecurityAlgorithms.HmacSha256);
// ৪. Token object তৈরি
var token = new JwtSecurityToken(
issuer: configuration["Jwt:Issuer"],
audience: configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(60),
signingCredentials: credentials);
// ৫. String হিসেবে return
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
একবারই
▼
OnModelCreating এ seed data দিলে প্রতি database update এ check করে — না থাকলে নিজে তৈরি করে। ম্যানুয়ালি SQL লেখার দরকার নেই।
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
var adminRoleId = "a71a55ad-7f0b-4cf9-9291-67a96c21b5a2";
var readerRoleId = "c32dc752-b293-41fa-ad1d-f23605833215";
var adminUserId = "d6e321e8-3486-4f3d-979b-22d7a26f043e";
// Roles
builder.Entity<IdentityRole>().HasData(new List<IdentityRole>
{
new IdentityRole { Id = adminRoleId, Name = "Admin",
NormalizedName = "ADMIN" },
new IdentityRole { Id = readerRoleId, Name = "Reader",
NormalizedName = "READER" }
});
// Admin user
var adminUser = new IdentityUser
{
Id = adminUserId,
UserName = "admin@myblog.com",
Email = "admin@myblog.com",
NormalizedEmail = "ADMIN@MYBLOG.COM",
NormalizedUserName = "ADMIN@MYBLOG.COM"
};
adminUser.PasswordHash = new PasswordHasher<IdentityUser>()
.HashPassword(adminUser, "Admin@123");
builder.Entity<IdentityUser>().HasData(adminUser);
// Admin user → Admin role
builder.Entity<IdentityUserRole<string>>().HasData(
new IdentityUserRole<string>
{
RoleId = adminRoleId,
UserId = adminUserId
});
}
dotnet ef database update
গুরুত্বপূর্ণ
▼
দুটো endpoint — /api/auth/register নতুন reader তৈরি করে, /api/auth/login JWT token return করে।
public class LoginRequestDto
{
[Required][EmailAddress]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
public class RegisterRequestDto
{
[Required][EmailAddress]
public string Email { get; set; }
[Required][MinLength(6)]
public string Password { get; set; }
}
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly UserManager<IdentityUser> userManager;
private readonly ITokenService tokenService;
public AuthController(UserManager<IdentityUser> userManager,
ITokenService tokenService)
{
this.userManager = userManager;
this.tokenService = tokenService;
}
// POST /api/auth/login
[HttpPost("login")]
public async Task<IActionResult> Login(
[FromBody] LoginRequestDto request)
{
var user = await userManager.FindByEmailAsync(request.Email);
if (user != null)
{
var ok = await userManager
.CheckPasswordAsync(user, request.Password);
if (ok)
{
var roles = await userManager.GetRolesAsync(user);
var token = tokenService
.CreateJwtToken(user, roles.ToList());
return Ok(new { Email = request.Email,
Token = token, Roles = roles });
}
}
return BadRequest("Invalid Email or Password");
}
// POST /api/auth/register
[HttpPost("register")]
public async Task<IActionResult> Register(
[FromBody] RegisterRequestDto request)
{
var user = new IdentityUser
{
UserName = request.Email,
Email = request.Email
};
var result = await userManager
.CreateAsync(user, request.Password);
if (result.Succeeded)
{
var roleResult = await userManager
.AddToRoleAsync(user, "Reader");
if (roleResult.Succeeded)
return Ok("User registered successfully!");
}
return BadRequest(result.Errors);
}
}
শেষ ধাপ
▼
Token ছাড়া কেউ sensitive endpoint access করতে পারবে না। Role-based বা শুধু authenticated user দুইভাবেই করা যায়।
// শুধু logged-in user
[Authorize]
// শুধু Admin role
[Authorize(Roles = "Admin")]
// Admin অথবা Reader
[Authorize(Roles = "Admin,Reader")]
// উদাহরণ — শুধু Admin delete করতে পারবে
[Authorize(Roles = "Admin")]
[HttpDelete("{id:Guid}")]
public async Task<IActionResult> DeleteBlogPost(Guid id)
{
// লজিক...
}
Swagger থেকে test করতে হলে Authorize button এ গিয়ে Bearer <token> format এ token paste করতে হবে।
Admin@123