asp.net-mvc - español - microsoft asp.net mvc 2 que es
Asp.net MVC Autorizar el atributo, redirigir a la página personalizada "sin derechos" (5)
Como se sugiere en la autorización de Customizing en ASP.NET MVC , puede crear una subclase de AuthorizeAttribute para interceptar el escenario autenticado pero no autorizado y reemplazar el resultado con un redireccionamiento.
Asp.net MVC2 redirecciona a la página de inicio de sesión con la response 302
cuando el usuario autenticado no tiene derechos.
Me gustaría dividirme en dos acciones
- Si el usuario no está autenticado, haga lo que hace, redirija a la página de inicio de sesión.
- Si el usuario está autenticado pero no tiene los derechos requeridos, devuelva el código de estado de HTTP apropiado y no muestre ninguna página de derechos.
¿Hay alguna forma de hacerlo? ¿O estoy haciendo algo mal con autorizar y autenticar formularios? La única forma en que puedo pensar es escribiendo el atributo de autorizar personalizado, que quiero evitar.
De forma similar a las soluciones sugeridas por @hellangle y @Andreas, utilicé el siguiente código para resolver este problema:
public class CustomizedAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var userAuthInfo = GetUserAuthInfo();
if (!userAuthInfo.IsAuthenticated())
{
filterContext.Result = new RedirectResult(UrlToYourLoginPage);
return;
}
if (!userAuthInfo.IsAuthorized())
{
var result = new ViewResult {ViewName = "UnAuthorized"};
result.ViewBag.Message = "Sorry! You are not authorized to do this!";
filterContext.Result = result;
}
}
}
Por supuesto, debe implementar la clase de información de autorización del usuario y los métodos relacionados (GetUserAuthInfo, IsAuthenticated, IsAuthorized) según sus necesidades específicas. Además, una vista llamada ''UnAuthorized'' debe colocarse en algún lugar que el motor MVC pueda encontrar. Luego se puede usar en una clase de controlador (señalada en la respuesta de @hellangle) o en un método de acción:
[CustomizedAuthorizeAttribute]
public class TargetController : Controller
{
[CustomizedAuthorizeAttribute]
public ActionResult TargetAction()
{
// Your Code
}
}
Para proporcionar una estrategia de control de acceso diferente para varias clases de controlador y métodos de acción, implementa un constructor para la clase CustomizedAuthorizeAttribute que acepta los parámetros que representan la información de control de acceso y luego crea una instancia de la clase CustomizedAuthorizeAttribute en consecuencia.
Implemente un AuthorizeAttribute
personalizado y agregue la siguiente anulación. Lo básico es verificar si el usuario está autenticado pero no autorizado y luego redireccionar a su propia página "Acceso denegado". ¡Espero que esto ayude!
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// Check if user is authenticated and if this action requires authorization
if (filterContext.HttpContext.User.Identity.IsAuthenticated
&& filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), true))
{
List<object> attributes = new List<object>(filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
// Check all authorzation attributes
foreach (var attribute in attributes)
{
var authAttribute = attribute as AuthorizeAttribute;
if (authAttribute != null)
{
if (!filterContext.HttpContext.User.IsInRole(authAttribute.Roles))
{
// User is not authorized so redirect to our access denied error page
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "area", "" },
{ "controller", "Error" },
{ "action", "AccessDenied" }
});
break;
}
}
}
}
}
Puede escribir un atributo de autorización personalizado y en el método AuthorizeCore si el usuario no está autenticado, regrese un HttpUnauthorizedResult y, si está autenticado pero no en roles, realice alguna otra acción que le gustaría. Tenga en cuenta que si devuelve el código de estado 401, el marco de FormsAuthentication eventualmente lo redirigirá con 302 a la página de inicio de sesión.
Puede escribir un atributo de filtro personalizado como este:
public class CustomAuthorizeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?returnUrl=" +
filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
}
//Check user right here
if (userNotRight)
{
filterContext.HttpContext.Response.StatusCode = 302;
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
Y usarlo en el controlador:
[CustomAuthorize]
public class HomeController : Controller
{
}