2012-06-07 19 views
18

He leídoredirigida a otra página cuando el usuario no está autorizado en MVC3 asp.net

How to easily redirect if not authenticated in MVC 3? y Redirect to AccessDenied page when user is not authorized pero el enlace de una respuesta (significa http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/) no funciona.

pongo

[Authorize(Users = "test")] 
    public class RestrictedPageController: Controller 
    { 

     public ActionResult Index() 
     { 
      return View(); 
     } 

.... 
    } 

Y en mi web.config, ya tengo

<authentication mode="Forms"> 
     <forms loginUrl="~/Account/LogOn" timeout="2880" /> 
</authentication> 

en consecuencia con https://stackoverflow.com/a/6770583/998696

Pero cuando quiero acceder /RestrictedPage/Index, debe redirigir a mí otra página (desde otro controlador). En lugar de esto, aparece el error como:

Server Error in '/Project' Application. 

The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched: 
~/Views/Account/LogOn.aspx 
~/Views/Account/LogOn.ascx 
~/Views/Shared/LogOn.aspx 
~/Views/Shared/LogOn.ascx 
~/Views/Account/LogOn.cshtml 
~/Views/Account/LogOn.vbhtml 
~/Views/Shared/LogOn.cshtml 
~/Views/Shared/LogOn.vbhtml 

Antes de inicio de sesión, la forma Logon página aparece correctamente, pero aparece el error anterior cuando se accede a la página /RestrictedPage/Index. Puedo iniciar sesión con un usuario diferente autorizado para acceder a la página RestrictedPage.

¿Dónde está mi error y cómo configurar la redirección?

Respuesta

47

El valor predeterminado Authorize atributo se comporta de una manera tal que no cuando el usuario está autenticado o autenticado pero no autorizada entonces se establece el código de estado como 401 (no autorizado). Cuando el filtro establece el código de estado como , el marco ASP.NET comprueba si el sitio web tiene habilitada la autenticación de formularios y si se redirecciona al parámetro loginUrl configurado allí.

Si desea cambiar ese comportamiento que usted quiere redirigir al usuario a un controlador AccessDenied si el usuario es autenticado, pero no autorizada entonces usted tiene que extender el atributo Authorize y reemplazar el método HandleUnauthorizedRequest.

Por ej.

public class CustomAuthorize: AuthorizeAttribute 
{ 
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      filterContext.Result = new HttpUnauthorizedResult(); 
     } 
     else 
     { 
      filterContext.Result = new RedirectToRouteResult(new 
       RouteValueDictionary(new { controller = "AccessDenied" })); 
     } 
    } 
} 

Puede anular la HandleUnauthorizedRequest según su necesidad y después hay que marcar las acciones del controlador a utilizar el atributo CustomAuthorize en lugar de la incorporada en uno.

+0

Upvote y aceptaron! Un comentario: debe utilizar 'protected override void HandleUnauthorizedRequest (AuthorizationContext filterContext) {' para anular el método; de lo contrario, no funcionará –

+0

Gracias por señalar que ... ¡fijo a la vez! – VJAI

1

Sí, es correcto como usted ha mencionado en web.config

<forms loginUrl="~/Account/LogOn" timeout="2880" /> 

redirección está buscando el controlador de la cuenta y ActionResult inicio de sesión. Si desea redirigir su página, cambiar allí en vez de la cuenta y abrir una sesión

2

Place "/ Cuenta/inicio de sesión" en lugar de "~/Cuenta/inicio de sesión"

3

me gusta respuesta de Marcos,
pero no quiero cambiar todo de mi acción atribuye
de [Autorizar] a [CustomAuthorize]

edito Login() acción sobre AccountController
y comprobar Request.IsAuthenticated antes del espectáculo vista
Creo que, si el usuario autenticado ir a /Account/Logon,
I se redireccionará a /Error/AccessDenied.

[AllowAnonymous] 
    public ActionResult Login(string returnUrl) 
    { 
     if (Request.IsAuthenticated) 
     { 
      return RedirectToAction("AccessDenied", "Error"); 
     } 

     ViewBag.ReturnUrl = returnUrl; 

     return View(); 
    } 
+0

pero en este caso, si ya ha iniciado sesión y va a la página de inicio de sesión, verá '/ error/accessDenied' en lugar de'/account/login', ¿verdad? Si no desea cambiar '[Authorize]' to '[CustomAuthorize]', siempre puede ponerle el nombre 'YourBrand.YourProject.Security.AuthorizeAttribute' y luego hacer una referencia a' YourBrand.YourProject.Security' o alguna cosa – percebus

0

Como yo no quiero anular AuthorizeAttribute que utiliza el filtro

public class RedirectFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

     if (!IsAuthorized(filterContext)) 
     { 
      filterContext.Result = 
       new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"})); 
     } 
    } 

    private bool IsAuthorized(ActionExecutingContext filterContext) 
    { 
     var descriptor = filterContext.ActionDescriptor; 
     var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute; 

     if (authorizeAttr != null) 
     { 
      if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString())) 
      return false; 
     } 
     return true; 

    } 
} 
Cuestiones relacionadas