I'm new to ASP.NET Core and currently working on a project called Clinic Management
. Within this project, I've defined three roles: Admin
, Doctor
and Patient
. My current challenge is implementing the functionality using the built-in IdentityRole
class. Specifically, I want to assign the Admin
role to users when they first register, but I'm struggling with this step. Furthermore, I'm unsure about the best practices for managing these roles. Currently, I've manually added them to the AspNetRoles
table, but I'm uncertain if this is the recommended approach. Here's my AccountController
where I should handle this logic.
using ClinicManagement.Models;
using ClinicManagement.ViewModels;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ClinicManagement.Controllers
{
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> userManager;
private readonly SignInManager<ApplicationUser> signInManager;
private readonly RoleManager<IdentityRole> roleManager;
public AccountController(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager, RoleManager<IdentityRole> roleManager)
{
this.userManager = userManager;
this.signInManager = signInManager;
this.roleManager = roleManager;
}
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
// Copy data from RegisterViewModel to IdentityUser
var user = new ApplicationUser
{
UserName = model.Name,
Email = model.Email
};
// Store user data in AspNetUsers database table
var result = await userManager.CreateAsync(user, model.Password);
// If user is successfully created, sign-in the user using
// SignInManager and redirect to index action of HomeController
if (result.Succeeded)
{
await signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("index", "home");
}
// If there are any errors, add them to the ModelState object
// which will be displayed by the validation summary tag helper
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return View(model);
}
[HttpPost]
public async Task<IActionResult> Logout()
{
await signInManager.SignOutAsync();
return RedirectToAction("index", "home");
}
[HttpGet]
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
var result = await signInManager.PasswordSignInAsync(
model.Email, model.Password, model.RememberMe, false);
if (result.Succeeded)
{
return RedirectToAction("index", "home");
}
ModelState.AddModelError(string.Empty, "Invalid Login Attempt");
}
return View(model);
}
}
}
I tried several things
There is official way to manage the roles https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.rolemanager-1?view=aspnetcore-7.0
You can add roles this way:
In program.cs
builder.Services.AddDefaultIdentity<IdentityUser>(...)
.AddRoles<IdentityRole>() // Add this
...
in your register action
//I set in my register.cshtml.cs
public class RegisterModel : PageModel
{
...
private readonly RoleManager<IdentityRole> _roleManager;
public RegisterModel(
...
RoleManager<IdentityRole> roleManager)
{
...
_roleManager = roleManager;
}
...
//Afer user created, create the role
var role = new IdentityRole("Admin");
await _roleManager.CreateAsync(role);
//add the role to user
await _userManager.AddToRoleAsync(user, "Admin");
...
Add the [authorize] attribute on your actions to execute
[Authorize(Roles = "Admin")]
public async Task<IActionResult> RoleCheck()
{
...
}
AspNetRoles table
Role binded in AspNetUserRoles
Correct role will be passed and wrong get denied