tutorial - ASP.NET MVC redirige a una página de acceso denegado usando un proveedor de rol personalizado
membership visual studio 2017 (8)
Estoy creando un proveedor de roles personalizado y establezco un atributo de Autorización que especifica un rol en mi controlador y está funcionando bien, así:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
Pero cuando un usuario no tiene acceso a este controlador, se le redirige a la página de inicio de sesión. ¿Cómo puedo redirigirlo a una página "AcessDenied.aspx"?
Aquí está mi solución, basada en la respuesta de eu-ge-ne. El mío redirige correctamente al usuario a la página de inicio de sesión si no ha iniciado sesión, pero a una página de acceso denegado si ha iniciado sesión pero no está autorizado para ver esa página.
[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
AccessDeniedAuthorizeAttribute.cs:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("~/Account/Logon");
return;
}
if (filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/Account/Denied");
}
}
}
AccountController.cs:
public ActionResult Denied()
{
return View();
}
Vistas / Cuenta / Denegado.cshtml: (Sintaxis de Razor)
@{
ViewBag.Title = "Access Denied";
}
<h2>@ViewBag.Title</h2>
Sorry, but you don''t have access to that page.
Construí sobre la respuesta de Vic para permitirme tener una página de Acceso denegado diferente para cada una de las áreas de la aplicación. Lo hizo al devolver un RedirectToRouteResult
, que en lugar de redirigir a una URL relativa a la raíz de la aplicación, redirige al controlador y la acción del área actual:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedController { get; set; }
public string AccessDeniedAction { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (String.IsNullOrWhiteSpace(AccessDeniedController) || String.IsNullOrWhiteSpace(AccessDeniedAction))
{
AccessDeniedController = "Home";
AccessDeniedAction = "AccessDenied";
}
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = AccessDeniedController, Action = AccessDeniedAction }));
}
}
}
Eche un vistazo a la Answer de tvanfosson de esta pregunta muy similar : Esto es lo que estoy haciendo (Gracias a tvanfosson), así que ahora solo tengo que decir:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...
Si el usuario no está en el rol, obtendrán la vista especificada por ViewName.
Redirigir no siempre es la mejor solución.
Utilice el código http estándar 403:
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
Solo una pequeña actualización de Vic Alcazar, Detalles agregados de la url de solicitud en redirección Para que pueda registrar los detalles del acceso denegado y por quién si lo desea
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedViewName { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
AccessDeniedViewName = "~/Account/AccessDenied";
var requestUrl = filterContext.HttpContext.Request.Url;
filterContext.Result = new RedirectResult(String.Format("{0}?RequestUrl={1}", AccessDeniedViewName, requestUrl));
}
}
}
Una ligera mejora en la respuesta de Matt al evitar la necesidad de codificar la página de inicio de sesión y, opcionalmente, configurar la vista de acceso denegado dentro del atributo:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public string AccessDeniedViewName { get; set; }
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
filterContext.Result is HttpUnauthorizedResult)
{
if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
AccessDeniedViewName = "~/Account/AccessDenied";
filterContext.Result = new RedirectResult(AccessDeniedViewName);
}
}
}
[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
AccessDeniedAuthorizeAttribute.cs:
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if(filterContext.Result is HttpUnauthorizedResult)
{
filterContext.Result = new RedirectResult("~/AcessDenied.aspx");
}
}
}
public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.Result is HttpUnauthorizedResult && WebSecurity.IsAuthenticated)
{
filterContext.Result = new RedirectResult("~/Account/AccessDenied");
}
}
}