Me encontré con este problema hace unos días y la solución es un poco detallada, pero aquí están las partes importantes. En AuthorizeAttribute
, el método OnAuthorization
devuelve HttpUnauthorizedResult
cuando falla la autorización, lo que hace que devolver un resultado personalizado sea un poco difícil.
Lo que terminé haciendo fue crear una clase CustomAuthorizeAttribute y anular el método OnAuthorization para lanzar una excepción. Luego puedo detectar esa excepción con un controlador de errores personalizado y mostrar una página de error personalizada en lugar de devolver un 401 (no autorizado).
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public virtual void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
if (AuthorizeCore(filterContext.HttpContext)) {
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else {
// auth failed, redirect to login page
// filterContext.Result = new HttpUnauthorizedResult();
throw new HttpException ((int)HttpStatusCode.Unauthorized, "Unauthorized");
}
}
}
entonces en su web.config puede establecer manejadores personalizados para errores específicos:
<customErrors mode="On" defaultRedirect="~/Error">
<error statusCode="401" redirect="~/Error/Unauthorized" />
<error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
y luego poner en práctica su propia ErrorController para servir páginas personalizadas.
En IIS7 debe buscar en la configuración Response.TrySkipIisCustomErrors = true;
para habilitar sus errores personalizados.
así que usando esa lógica, tendría que devolver vistas parciales con "mensajes amistosos" correctos? ¿No es posible abarcar todo el método de acción con un atributo que hace lo mismo? – Kyle
Agregué un ejemplo arriba. Su otra opción es, por supuesto, escribir su propio atributo como usted mencionó (que sería la prueba más limpia, aunque más dura para la unidad), pero definitivamente no es un enfoque listo para usar. –