2009-08-14 13 views
28

Sto creando un provider di ruoli personalizzato e ho impostato un attributo Autorizza specificando un ruolo nel mio controller e sta lavorando bene, come questo:ASP.NET MVC redirect ad una pagina negato l'accesso utilizzando un ruolo personalizzato fornitore

[Authorize(Roles="SuperAdmin")] 
public class SuperAdminController : Controller 
... 

Ma quando un utente non ha accesso a questo controller, viene reindirizzato alla pagina di accesso. Come posso reindirizzare a una pagina "AcessDenied.aspx"?

risposta

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

Se l'utente è connesso e tenta di accedere alla pagina, verrà reindirizzato alla pagina AccessDenied. Buona. Ma, se l'utente non ha effettuato l'accesso, verrà reindirizzato alla pagina AccessDenied. Cattivo.In quella situazione, dovrebbero essere reindirizzati alla pagina di accesso. –

+3

Se si desidera reindirizzare la pagina normalmente nel caso in cui l'utente non sia più in, dopo la chiamata al metodo base.OnAuthorization(), aggiungere un'istruzione if attorno al resto del codice che controlla se Threading.Thread.CurrentPrincipal. Identity.IsAuthenticated. In questo modo l'utente viene indirizzato alla pagina AccessDenied a meno che l'utente non sia autenticato ... nel qual caso eseguirà l'azione predefinita (reindirizzamento alla pagina di accesso) – Frinavale

+0

dove viene inserita questa classe? nel controller? – Jay

8

diano un'occhiata al tvanfosson s' Answer da this very similar question, questo è quello che sto facendo (Grazie a tvanfosson), così ora non mi resta che dire:

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

Se l'utente non è nel ruolo, che riceveranno vista Thew specificato da ViewName.

22

Ecco la mia soluzione, basata sulla risposta di eu-ge-ne. Il mio reindirizza correttamente l'utente alla pagina di accesso se non ha effettuato l'accesso, ma a una pagina di accesso negato se ha effettuato l'accesso ma non è autorizzato a visualizzare tale pagina.

[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(); 
} 

Vista/account/Denied.cshtml: (sintassi Razor)

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

<h2>@ViewBag.Title</h2> 

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

Modifica perfetta dalla risposta accettata, grazie fratello –

6

Una leggera miglioramento della risposta di Matt b y evitando la necessità di hard-code nella pagina di accesso e l'impostazione opzionalmente l'accesso vista negato all'interno dell'attributo:

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

Ho costruito sulla risposta di Vic per consentirmi di avere una diversa pagina di accesso negato per ciascuna delle aree dell'applicazione. Ha fatto restituendo un RedirectToRouteResult invece, che invece di reindirizzare a un URL relativo alla radice dell'applicazione che reindirizza al controllore di area corrente e di azione:

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

Solo un piccolo aggiornamento per Vic Alcazar, Aggiunto dettagli della richiesta di URL di reindirizzamento in in modo che possa registrare i dettagli della accesso negato e da chi, se vogliono

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

reindirizzamento non è sempre la soluzione migliore

Usa stan dard http code 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
Problemi correlati