Answered by:
User Roles and Authentication.

Question
-
User-1694438709 posted
Currently spending my time at home building an Application in MVC ASP.Net Core for a college assignment. I've managed to get both a login and registration form working and I'm now looking at User Roles and Authentication. Just looking for some guidance on the best way of doing this.
Currently I have a 'Roles' field entered into my DB with either 'Admin' and 'User', I then made an 'Admin' and 'Users' Controller linking them to different pages:
[Authorize(Roles="Admin")] public class AdminController : Controller { private readonly DefaultContext _context; public AdminController(DefaultContext context) { _context = context; } public IActionResult Index() { return View(); } }
I'm not quite sure on how I go about checking the [Authorize(Roles="Admin")] to the 'Roles' column within my database?
Friday, March 27, 2020 1:08 PM
Answers
-
User711641945 posted
Hi binaary,
Here is a working demo like below:
1.Model:
public class User { public int Id { get; set; } public string UserName { get; set; } public string Password { get; set; } public int RoleId { get; set; } public Role Role { get; set; } } public class Role { public int Id { get; set; } public string Name { get; set; } public List<User> Users { get; set; } }
2.VIew:
@model User <h4>User</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Login" asp-route-returnUrl="@ViewData["ReturnUrl"]"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="UserName" class="control-label"></label> <input asp-for="UserName" class="form-control" /> <span asp-validation-for="UserName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Password" class="control-label"></label> <input asp-for="Password" class="form-control" /> <span asp-validation-for="Password" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div>
3.UsersController:
public class UsersController : Controller { private readonly YourContext _context; public UsersController(YourContext context) { _context = context; } public IActionResult Login(string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); } //[AllowAnonymous] [HttpPost] public async Task<IActionResult> Login(User userModel,string returnUrl = null) { if (ModelState.IsValid) { var user = _context.User.Include(u => u.Role) .Where(u => u.UserName==userModel.UserName && u.Password == userModel.Password) .FirstOrDefault(); var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.Role, user.Role.Name) }; ClaimsIdentity userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity); var authProperties = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(10) }; await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,principal, authProperties); return LocalRedirect(returnUrl); } else { ModelState.AddModelError("Password", "Email and/or Password wrong"); return View(); } } }
4.HomeController:
[Authorize(Roles= "Admin")] public class HomeController : Controller { [AllowAnonymous] public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } }
5.Startup.cs:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Users/Login"; options.LogoutPath = "/Users/Logout"; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<AuthenticationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("AuthenticationContext"))); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } }
Result:
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, March 31, 2020 8:54 AM
All replies
-
User475983607 posted
Currently spending my time at home building an Application in MVC ASP.Net Core for a college assignment. I've managed to get both a login and registration form working and I'm now looking at User Roles and Authentication. Just looking for some guidance on the best way of doing this.
Currently I have a 'Roles' field entered into my DB with either 'Admin' and 'User', I then made an 'Admin' and 'Users' Controller linking them to different pages:
[Authorize(Roles="Admin")] public class AdminController : Controller { private readonly DefaultContext _context; public AdminController(DefaultContext context) { _context = context; } public IActionResult Index() { return View(); } }
I'm not quite sure on how I go about checking the [Authorize(Roles="Admin")] to the 'Roles' column within my database?
Security works out-of-the-box. Just create a new project using the Identity template.
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new
Friday, March 27, 2020 1:35 PM -
User-1694438709 posted
Hey! Thanks for the reply.
Sadly due to it being for a college assignment, I'm not allowed to use this!
Friday, March 27, 2020 1:59 PM -
User711641945 posted
Hi binaary,
Here is a working demo like below:
1.Model:
public class User { public int Id { get; set; } public string UserName { get; set; } public string Password { get; set; } public int RoleId { get; set; } public Role Role { get; set; } } public class Role { public int Id { get; set; } public string Name { get; set; } public List<User> Users { get; set; } }
2.VIew:
@model User <h4>User</h4> <hr /> <div class="row"> <div class="col-md-4"> <form asp-action="Login" asp-route-returnUrl="@ViewData["ReturnUrl"]"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="UserName" class="control-label"></label> <input asp-for="UserName" class="form-control" /> <span asp-validation-for="UserName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Password" class="control-label"></label> <input asp-for="Password" class="form-control" /> <span asp-validation-for="Password" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> </div> </div>
3.UsersController:
public class UsersController : Controller { private readonly YourContext _context; public UsersController(YourContext context) { _context = context; } public IActionResult Login(string returnUrl = null) { ViewData["ReturnUrl"] = returnUrl; return View(); } //[AllowAnonymous] [HttpPost] public async Task<IActionResult> Login(User userModel,string returnUrl = null) { if (ModelState.IsValid) { var user = _context.User.Include(u => u.Role) .Where(u => u.UserName==userModel.UserName && u.Password == userModel.Password) .FirstOrDefault(); var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.Role, user.Role.Name) }; ClaimsIdentity userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity); var authProperties = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTime.UtcNow.AddMinutes(10) }; await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,principal, authProperties); return LocalRedirect(returnUrl); } else { ModelState.AddModelError("Password", "Email and/or Password wrong"); return View(); } } }
4.HomeController:
[Authorize(Roles= "Admin")] public class HomeController : Controller { [AllowAnonymous] public IActionResult Index() { return View(); } public IActionResult Privacy() { return View(); } }
5.Startup.cs:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options => { options.LoginPath = "/Users/Login"; options.LogoutPath = "/Users/Logout"; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<AuthenticationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("AuthenticationContext"))); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } }
Result:
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, March 31, 2020 8:54 AM