2012-06-07 8 views
18

Ho lettoRedirect a un'altra pagina quando l'utente non è autorizzato in asp.net MVC3

How to easily redirect if not authenticated in MVC 3? e Redirect to AccessDenied page when user is not authorized ma il collegamento da una risposta (significa http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/) non funziona.

ho messo

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

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

.... 
    } 

E nel mio web.config, ho già

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

conseguenza con https://stackoverflow.com/a/6770583/998696

Ma quando voglio accedere /RestrictedPage/Index, mi deve reindirizzare a altra pagina (da altro controller). Invece di questo, l'errore appare come:

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 

Prima di login, la forma Logon pagina compare correttamente, ma l'errore di cui sopra appare quando si accede /RestrictedPage/Index pagina. Posso accedere con utente diverso uno autorizzato ad accedere alla pagina RestrictedPage.

Dov'è il mio errore e come il reindirizzamento della configurazione?

risposta

47

L'impostazione predefinita Authorize attributo si comporta in modo tale che non quando l'utente è autenticato o autenticato ma non autorizzato allora impostare il codice di stato come 401 (Non autorizzato). Quando il filtro imposta il codice di stato come , il framework ASP.NET verifica se il sito Web ha l'autenticazione dei moduli abilitata e se è quindi reindirizzato al parametro impostato lì.

Se si vuole modificare l'azione che si desideri reindirizzare l'utente a un controller AccessDenied se l'utente è autenticato, ma non autorizzato, allora si deve estendere l'attributo Authorize e l'override del metodo HandleUnauthorizedRequest.

Per es.

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

È possibile ignorare il HandleUnauthorizedRequest secondo le vostre necessità e poi si deve segnare le azioni di controllo per utilizzare l'attributo CustomAuthorize al posto del built-in uno.

+0

Upvote e accettato! Una nota: deve usare 'protected override void HandleUnauthorizedRequest (AuthorizationContext filterContext) {' per sovrascrivere il metodo, altrimenti non funzionerà –

+0

Grazie per aver puntato che .. risolto atonce! – VJAI

1

Sì, è corretto come lei ha ricordato nel web.config

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

reindirizzamento è alla ricerca di controllo del conto e l'accesso ActionResult. Se si desidera reindirizzare la tua pagina, cambia lì, invece di account e accedere

2

Place "/ Account/LogOn" Invece di "~/account/accesso"

3

Mi piace risposta di Marco,
ma io non voglio cambiare tutta la mia azione attributi
da [Autorizza] a [CustomAuthorize]

modifico Login() azione su AccountController
e controllo Request.IsAuthenticated prima dello spettacolo vista
Penso che, se l'utente autenticato andare a /Account/Logon,
I reindirizzerà a /Error/AccessDenied.

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

     ViewBag.ReturnUrl = returnUrl; 

     return View(); 
    } 
+0

ma in questo caso, se hai già effettuato il login e vai alla pagina di accesso, vedrai un '/ error/accessDenied' invece di'/account/login', giusto? Se non si desidera modificare '[Autorizza]' per '[CustomAuthorize]' si può sempre chiamarlo 'YourBrand.YourProject.Security.AuthorizeAttribute' e quindi fare solo un riferimento a' YourBrand.YourProject.Security' o qualcosa – percebus

0

Dal momento che non volevo ignorare AuthorizeAttribute ho usato 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; 

    } 
} 
Problemi correlati