This tutorial assumes you’re building an MVC app that also exposes APIs or wants token-based login.
🔹 Step 1: Create ASP.NET Core MVC Project
🔹 Step 2: Install Required NuGet Packages
🔹 Step 3: Add JWT Settings in appsettings.json
⚠️ Use a long, secure key (store it in User Secrets or Azure Key Vault in production).
🔹 Step 4: Configure JWT in Program.cs
🔹 Step 5: Create a Model for Login
Models/LoginModel.cs
🔹 Step 6: Create Token Service
Services/TokenService.cs
🔹 Step 7: Create Authentication Controller
Controllers/AuthController.cs
🔹 Step 8: Protect Your MVC Controllers
Example: Controllers/HomeController.cs
🔹 Step 9: Test the Flow
-
Run the project →
https://localhost:5001/api/auth/login
Send POST request with:Response:
-
Use this token in Authorization Header:
-
Access
https://localhost:5001/home/index→ works only with valid JWT.
Accesshttps://localhost:5001/home/adminonly→ works only if role is"Admin".
Database → Login → Get Role → Generate JWT → [Authorize(Roles = "...")]
Your current GenerateToken(username, role) is already suitable. The main question is how to store and retrieve the role.
1. Simple approach: Role column in Users table
For your current requirement, you can keep it very simple:
CREATE TABLE Users(Id INT PRIMARY KEY IDENTITY(1,1),Username VARCHAR(100) NOT NULL UNIQUE,PasswordHash VARCHAR(500) NOT NULL,Role VARCHAR(50) NOT NULL,IsActive BIT NOT NULL DEFAULT 1);
Example data:
| Id | Username | Role | IsActive |
|---|---|---|---|
| 1 | shiva | Admin | 1 |
| 2 | amit | Faculty | 1 |
| 3 | raj | FrontDesk | 1 |
2. During login, get the role from database
For example:
var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username && x.IsActive);if (user == null){return Unauthorized();}
After validating the password:
var token = GenerateToken(user.Username,user.Role);
So if the database contains:
amit | Faculty
you automatically generate:
Username = amitRole = Faculty
You don't need to manually decide the role in your controller.
3. Your GenerateToken stays almost the same
public string GenerateToken(string username, string role){var jwtSettings = _config.GetSection("Jwt");var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"]));var claims = new[]{new Claim(ClaimTypes.Name, username),new Claim(ClaimTypes.Role, role)};var credentials = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);var token = new JwtSecurityToken(issuer: jwtSettings["Issuer"],audience: jwtSettings["Audience"],claims: claims,expires: DateTime.UtcNow.AddHours(8),signingCredentials: credentials);return new JwtSecurityTokenHandler().WriteToken(token);}
4. Then authorization becomes very easy
Admin only
[Authorize(Roles = "Admin")]public IActionResult CreateBatch(){return Ok("Admin allowed");}
Faculty only
[Authorize(Roles = "Faculty")]public IActionResult MarkAttendance(){return Ok("Faculty allowed");}
Admin OR Faculty
Create Project[Authorize(Roles = "Admin,Faculty")]public IActionResult ViewBatch(){return Ok("Admin or Faculty allowed");}For your type of system
If you're building something like your student/batch/attendance management system,
I'd structure permissions roughly like:
SuperAdmin↓Admin↓Faculty↓FrontDeskBut don't rely on this hierarchy automatically. Define access explicitly:
Another Task for Multiple RolesDashboardAdmin ✅Faculty ✅FrontDesk ✅Add RegistrationAdmin ✅Faculty ❌FrontDesk ✅Create BatchAdmin ✅Faculty ❌FrontDesk ❌Mark AttendanceAdmin ✅Faculty ✅FrontDesk ❌Delete BatchAdmin ✅Faculty ❌FrontDesk ❌Recommended design for a larger application
I'd recommend this structure for your application.
Users
CREATE TABLE Users(Id INT PRIMARY KEY IDENTITY(1,1),Username VARCHAR(100) NOT NULL UNIQUE,PasswordHash VARCHAR(500) NOT NULL,IsActive BIT NOT NULL DEFAULT 1);Roles
CREATE TABLE Roles(Id INT PRIMARY KEY IDENTITY(1,1),RoleName VARCHAR(50) NOT NULL UNIQUE);Insert:
INSERT INTO Roles (RoleName)VALUES('Admin'),('Faculty'),('FrontDesk');UserRoles
CREATE TABLE UserRoles(UserId INT NOT NULL,RoleId INT NOT NULL,PRIMARY KEY (UserId, RoleId),FOREIGN KEY (UserId) REFERENCES Users(Id),FOREIGN KEY (RoleId) REFERENCES Roles(Id));Now you can have:
Users--------------------------------1 | shiva2 | amit3 | rajRoles--------------------------------1 | Admin2 | Faculty3 | FrontDeskAnd:
UserRoles--------------------------------UserId | RoleId1 | 12 | 23 | 3So:
Shiva → AdminAmit → FacultyRaj → FrontDesk
7. Multiple roles become possible
Suppose Shiva needs both Admin and Faculty:
UserRoles--------------------------------UserId | RoleId1 | 11 | 2Now:
Shiva├── Admin└── FacultyThis is much more flexible.
8. Login query
You can retrieve all roles for the logged-in user:
var user = await _context.Users.FirstOrDefaultAsync(x =>x.Username == username &&x.IsActive);if (user == null){return Unauthorized();}Then:
var roles = await _context.UserRoles.Where(x => x.UserId == user.Id).Select(x => x.Role.RoleName).ToListAsync();You might get:
roles =AdminFacultyThen generate the JWT with multiple role claims.
var claims = new List<Claim>{new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),new Claim(ClaimTypes.Name,user.Username)};foreach (var role in roles){claims.Add(new Claim(ClaimTypes.Role, role));}Now the JWT contains:
Name = ShivaRole = AdminRole = FacultyAnd both work:
[Authorize(Roles = "Admin")]and:
[Authorize(Roles = "Faculty")]
9. This is the architecture I recommend for you
Since you're building a system with Admin, Faculty and FrontDesk and likely want to add more roles later, use:
DATABASE│▼Users│▼UserRoles│▼Roles│▼Login│▼Generate JWT│┌────────┴────────┐▼ ▼Admin Faculty│ │└────────┬────────┘▼API Controller│▼[Authorize(Roles)]For example:
[Authorize(Roles = "Admin,Faculty")]public IActionResult MarkAttendance(){// Admin OR Faculty}and:
[Authorize(Roles = "Admin")]public IActionResult DeleteStudent(){// Admin only}
.webp)
0 Comments
POST Answer of Questions and ASK to Doubt