Reputation:
I am trying to restrict access to my controller's methods, through roles, in the traditional way, the complete controller rejects the authentication of roles for all users of all roles
Authorize Attribute with Multiple Roles
using MBC.ServiciosUtilidad.CatalogoUS.Implementacion;
using MBC.ServiciosEntidad.ReportesDmsES.Implementacion;
using System.Web.Mvc;
using MBC.Models.ReportDms;
using PagedList;
using System.Data;
using System.Linq;
using MBC.ModeloCanonico.Constantes;
using System.Web.Security;
using static MBC.ModeloCanonico.Constantes.CatalogoConstante;
namespace MBC.Controllers.Report.Vehiculos
{
[Authorize]
//[Authorize(Roles = CatalogoConstante.Rol.Administrador)]
public class ReportDmsVehiculosController : MasterController
{
private readonly ICatalogoUSContract _servicioCatalogo;
private readonly IReportesDmsESContrato _servicioReportesDms;
//CONSTRUCTOR
public ReportDmsVehiculosController()
{
_servicioCatalogo = new CatalogoUSImplementacion();
_servicioReportesDms = new ReportesDmsESImplementacion();
}
//[Authorize(Roles = CatalogoConstante.Rol.Administrador)]
[AuthorizeRoles(Rol.Administrador)]
public ActionResult ReportDmsVehiculos()
{
return View();
}
}
namespace MBC.ModeloCanonico.Constantes
{
public static class CatalogoConstante
{
public struct Rol
{
public const string Administrador = "Administrador";
public const string RecursosHumanos = "Recursos Humanos";
}
}
This is the login () with a return message, 'access denied'
public ActionResult Login()
{
//if (User.Identity.IsAuthenticated)
if (User.IsInRole("ProvideASpecificRoleHere"))
return RedirectToAction("Index", "Home");
if (User.Identity.IsAuthenticated)
ModelState.AddModelError("", "Acceso Denegado.");
return View();
}
for some reason he keeps sending me to: RedirectToAction ("Index", "Home"), This should only happen at the start
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
UserRol userRol = new UserRol();
userRol.user = _serviceUsuario.ValidarCredencialesRol(model.Usuario, model.Contrasena);
if (userRol.user != null)
{
model.Roles = userRol.user.Roles;
FormsAuthentication.SetAuthCookie(model.Usuario, false);
((ClaimsIdentity)HttpContext.User.Identity).AddClaim(new Claim(ClaimTypes.Role, model.Roles));
var authTicket = new FormsAuthenticationTicket(1, model.Usuario, DateTime.Now, DateTime.Now.AddMinutes(20), false, model.Roles);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Response.Cookies.Add(authCookie);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
UsuarioLogueado();
}
This is the verification function of the registered user. This class is used to obtain the information of the logged in user, to use as an audit and to show some data in the view.
protected void UsuarioLogueado()
{
try
{
if (User.Identity.IsAuthenticated)
{
var usuarioLogueado = Session["UsarioEntityModel"] as UsarioEntityModel;
if (usuarioLogueado == null)
{
usuarioLogueado = _userService.ObtenerUsuarioLogueado(User.Identity.Name).ToUsarioEntityModel();
((ClaimsIdentity)HttpContext.User.Identity).AddClaim(new Claim(ClaimTypes.Role, usuarioLogueado.Rol));
Session["UsarioEntityModel"] = usuarioLogueado;
}
ViewBag.usuarioLogueado = usuarioLogueado;
}
else
{
Session["UsarioEntityModel"] = null;
}
}
catch (AggregateException ex)
{
throw ex;
}
}
Upvotes: 1
Views: 659
Reputation: 1627
User this for code returning view with respect to a Specific role:
Instead of This:
public ActionResult Login()
{
if (User.Identity.IsAuthenticated)
return RedirectToAction("Index", "Home");
return View();
}
Try This:
public ActionResult Login()
{
if (User.IsInRole("ProvideASpecificRoleHere"))
return RedirectToAction("Index", "Home");
return View();
}
Upvotes: 0
Reputation: 687
As per provided code your adding Roles in user data of authentication ticket (Last Parameter of new FormsAuthenticationTicket()
. This user data can be utilized.
By default FormsAuthenticationTicket works with "Users" not with "Roles" so attribute
[Authorize(Users = "model.Usuario")]
will work but [Authorize(Roles= "Adminstrador")]
will give you Unauthorized.
To work with roles you need to add roles in HttpContext.User
from AuthTicket.
Add below method in your controller:-
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User != null)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
if (filterContext.HttpContext.User.Identity is FormsIdentity)
{
FormsIdentity id = (FormsIdentity)HttpContext.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.User = new GenericPrincipal(HttpContext.User.Identity, roles);
}
}
}
}
You can also create Authorization filter for same so that same can be used across your application.
If you override OnAuthorization, AuthorizeCore and HandleUnauthorizedRequest methods in your custom authorization class, then it will call OnAuthorization method, then if you call base.OnAuthorization(filterContext) method in overriden OnAuthorization method, then it will call AuthorizeCore method, if that return false, then it will call HandleUnauthorizedRequest method.
Upvotes: 2