I am very new to asp.net mvc and I am trying to implement users with their roles, at the time of giving the navbar options if I enter as "admin" these send me back to the login even though I am registered.
What I want is to send me to the Index of those controllers.
This is the controller that handles the login and logout:
public class AccountController : Controller
{
private readonly IUserHelper _userHelper;
public AccountController(IUserHelper userHelper)
{
_userHelper = userHelper;
}
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
var result = await _userHelper.LoginAsync(model);
if (result.Succeeded)
{
if (Request.Query.Keys.Contains("ReturnUrl"))
{
return Redirect(Request.Query["ReturnUrl"].First());
}
return RedirectToAction("Index", "Home");
}
ModelState.AddModelError(string.Empty, "Usuario o contrase?a erroneo! ");
}
return View(model);
}
[HttpGet]
public async Task<IActionResult> Logout()
{
await _userHelper.LogoutAsync();
return RedirectToAction("Index", "Home");
}
}
For example this is one of the controllers that I want only the "Admin" to access:
[Authorize(Roles = "Admin")]
public class AgendaController : Controller
{
private readonly DataContext _context;
public AgendaController(DataContext context)
{
_context = context;
}
// GET: Agenda
public async Task<IActionResult> Index()
{
return View(await _context.Agendas.ToListAsync());
}
// GET: Agenda/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var agenda = await _context.Agendas
.FirstOrDefaultAsync(m => m.Id == id);
if (agenda == null)
{
return NotFound();
}
return View(agenda);
}
// GET: Agenda/Create
public IActionResult Create()
{
return View();
}
// POST: Agenda/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Date,Remarks,IsAvailable")] Agenda agenda)
{
if (ModelState.IsValid)
{
_context.Add(agenda);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(agenda);
}
// GET: Agenda/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var agenda = await _context.Agendas.FindAsync(id);
if (agenda == null)
{
return NotFound();
}
return View(agenda);
}
// POST: Agenda/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Date,Remarks,IsAvailable")] Agenda agenda)
{
if (id != agenda.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(agenda);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AgendaExists(agenda.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(agenda);
}
// GET: Agenda/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var agenda = await _context.Agendas
.FirstOrDefaultAsync(m => m.Id == id);
if (agenda == null)
{
return NotFound();
}
return View(agenda);
}
// POST: Agenda/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var agenda = await _context.Agendas.FindAsync(id);
_context.Agendas.Remove(agenda);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool AgendaExists(int id)
{
return _context.Agendas.Any(e => e.Id == id);
}
}
I made use of helpers for these actions:
public class UserHelper : IUserHelper
{
private readonly UserManager<User> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly SignInManager<User> _signInManager;
public UserHelper(
UserManager<User> userManager,
RoleManager<IdentityRole> roleManager,
SignInManager<User> signInManager)
{
_userManager = userManager;
_roleManager = roleManager;
_signInManager = signInManager;
}
public async Task<SignInResult> LoginAsync(LoginViewModel model)
{
return await _signInManager.PasswordSignInAsync(
model.Username,
model.Password,
model.RememberMe,
false);
}
public async Task LogoutAsync()
{
await _signInManager.SignOutAsync();
}
public async Task<IdentityResult> AddUserAsync(User user, string password)
{
return await _userManager.CreateAsync(user, password);
}
public async Task AddUserToRoleAsync(User user, string roleName)
{
await _userManager.AddToRoleAsync(user, roleName);
}
public async Task CheckRoleAsync(string roleName)
{
var roleExists = await _roleManager.RoleExistsAsync(roleName);
if (!roleExists)
{
await _roleManager.CreateAsync(new IdentityRole
{
Name = roleName
});
}
}
public async Task<User> GetUserByEmailAsync(string email)
{
return await _userManager.FindByEmailAsync(email);
}
public async Task<bool> IsUserInRoleAsync(User user, string roleName)
{
return await _userManager.IsInRoleAsync(user, roleName);
}
}
Interface:
public interface IUserHelper
{
Task<User> GetUserByEmailAsync(string email);
Task<IdentityResult> AddUserAsync(User user, string password);
Task CheckRoleAsync(string roleName);
Task AddUserToRoleAsync(User user, string roleName);
Task<bool> IsUserInRoleAsync(User user, string roleName);
Task<SignInResult> LoginAsync(LoginViewModel model);
Task LogoutAsync();
}
Create a feed for the database and enter some records:
public class SeedDb
{
private readonly DataContext _dataContext;
private readonly IUserHelper _userHelper;
public SeedDb(
DataContext context,
IUserHelper userHelper)
{
_dataContext = context;
_userHelper = userHelper;
}
public async Task SeedAsync()
{
await _dataContext.Database.EnsureCreatedAsync();
await CheckRoles();
var manager = await CheckUserAsync("00148989898", "Juan", "Corderp", "[email protected]", "809 634 2747", "Admin");
var customer = await CheckUserAsync("40217655544", "Julieta", "Maria", "[email protected]", "829 634 2747", "Customer");
await CheckPetTypesAsync();
await CheckServiceTypesAsync();
await CheckOwnerAsync(customer);
await CheckManagerAsync(manager);
await CheckPetsAsync();
await CheckAgendasAsync();
}
private async Task CheckRoles()
{
await _userHelper.CheckRoleAsync("Admin");
await _userHelper.CheckRoleAsync("Customer");
}
private async Task<User> CheckUserAsync(string document, string firstName, string lastName, string email, string phone, string role)
{
var user = await _userHelper.GetUserByEmailAsync(email);
if (user == null)
{
user = new User
{
FirstName = firstName,
LastName = lastName,
Email = email,
UserName = email,
PhoneNumber = phone,
Document = document
};
await _userHelper.AddUserAsync(user, "123456");
await _userHelper.AddUserToRoleAsync(user, role);
}
return user;
}
private async Task CheckPetsAsync()
{
if (!_dataContext.Pets.Any())
{
var owner = _dataContext.Owners.FirstOrDefault();
var petType = _dataContext.PetTypes.FirstOrDefault();
AddPet("Otto", owner, petType, "Shih tzu");
AddPet("Killer", owner, petType, "Dobermann");
await _dataContext.SaveChangesAsync();
}
}
private async Task CheckServiceTypesAsync()
{
if (!_dataContext.ServiceTypes.Any())
{
_dataContext.ServiceTypes.Add(new ServiceType { Name = "Consulta" });
_dataContext.ServiceTypes.Add(new ServiceType { Name = "Urgencia" });
_dataContext.ServiceTypes.Add(new ServiceType { Name = "Vacunación" });
await _dataContext.SaveChangesAsync();
}
}
private async Task CheckPetTypesAsync()
{
if (!_dataContext.PetTypes.Any())
{
_dataContext.PetTypes.Add(new PetType { Name = "Perro" });
_dataContext.PetTypes.Add(new PetType { Name = "Gato" });
await _dataContext.SaveChangesAsync();
}
}
private async Task CheckOwnerAsync(User user)
{
if (!_dataContext.Owners.Any())
{
_dataContext.Owners.Add(new Owner { User = user });
await _dataContext.SaveChangesAsync();
}
}
private async Task CheckManagerAsync(User user)
{
if (!_dataContext.Managers.Any())
{
_dataContext.Managers.Add(new Manager { User = user });
await _dataContext.SaveChangesAsync();
}
}
private void AddPet(string name, Owner owner, PetType petType, string race)
{
_dataContext.Pets.Add(new Pet
{
Born = DateTime.Now.AddYears(-2),
Name = name,
Owner = owner,
PetType = petType,
Race = race