2009-08-14 16 views
28

Estoy creando un proveedor función personalizada y estableció un Autorizar atributo que especifica un papel en mi controlador y que está funcionando muy bien, como esto:ASP.NET MVC redirigir a una página de acceso denegado el uso de una función personalizada proveedor de

[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"?

Respuesta

42
[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"); 
     } 
    } 
} 
+6

Si el usuario inicia sesión e intenta acceder a la página, será redirigido a la página AccessDenied. Bueno. Pero, si el usuario no está conectado, será redireccionado a la página AccessDenied. Malo.En esa situación, deberían ser redirigidos a la página de inicio de sesión. –

+3

Si desea que la página se redirija normalmente en el caso de que el usuario ya no esté, después de la llamada al método base.OnAuthorization(), agregue una instrucción if alrededor del resto del código que comprueba si Threading.Thread.CurrentPrincipal. Identity.IsAuthenticated. De esta forma, se redirige al usuario a la página AccessDenied a menos que el usuario no esté autenticado ... en cuyo caso se realizará la acción predeterminada (redirigir a la página de inicio de sesión) – Frinavale

+0

¿dónde se pone esta clase? en el controlador? – Jay

8

miren tvanfosson 's Answer de this very similar question, esto es lo que estoy haciendo (Gracias a tvanfosson), por lo que ahora sólo tengo que decir:

[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")] 
public class SuperAdminController : Controller 
... 

Si el usuario no está en la función, obtendrán la vista especificada por ViewName.

22

Aquí está mi solución, basada en la respuesta de eu-ge-ne. Mina redirige correctamente al usuario a la página de inicio de sesión si no está conectado, pero a una página Acceso denegado si está conectado 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/Denied.cshtml: (sintaxis Razor)

@{ 
    ViewBag.Title = "Access Denied"; 
} 

<h2>@ViewBag.Title</h2> 

Sorry, but you don't have access to that page. 
+1

Modificación perfecta de la respuesta aceptada, gracias hermano –

6

Una ligera mejora a la respuesta de Matt b y evitando la necesidad de codificar la página de inicio de sesión y establecer opcionalmente la vista negado el acceso 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); 
     } 
    } 
} 
0
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"); 
      } 
     } 
    } 
0

He construido sobre la respuesta de Vic para permitir que tuviera una página de acceso denegado diferente para cada una de las áreas de la aplicación. Lo hizo mediante la devolución de un RedirectToRouteResult en cambio, que en lugar de volver a dirigir a una dirección URL relativa a la raíz de la aplicación redirige al controlador de la zona actual de y la acción:

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 })); 
     } 
    } 
} 
0

Sólo una pequeña actualización a Vic Alcazar, información Agregado de la URL de solicitud de redirección Así que puede registrar los detalles del acceso denegado y que si quieren

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)); 
     } 
    } 
} 
5

de redireccionamiento no es siempre la mejor solución

uso Stan código HTTP estándar 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
Cuestiones relacionadas