2009-08-14 4 views
28

Je crée un fournisseur de rôle personnalisé et je mis un Autorisez attribut spécifiant un rôle dans mon contrôleur et il fonctionne très bien, comme celui-ci:ASP.NET MVC redirection vers une page d'accès refusé à l'aide d'un fournisseur rôle personnalisé

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

Mais lorsqu'un utilisateur n'a pas accès à ce contrôleur, il est redirigé vers la page de connexion. Comment puis-je le rediriger vers une page "AcessDenied.aspx"?

Répondre

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 l'utilisateur est connecté et tente d'accéder à la page, il sera redirigé vers la page AccessDenied. Bien. Mais, si l'utilisateur n'est pas connecté, il sera redirigé vers la page AccessDenied. Mal.Dans ce cas, ils doivent être redirigés vers la page de connexion. –

+3

Si vous souhaitez que la page redirige normalement dans le cas où l'utilisateur ne se trouve plus, après l'appel de la méthode base.OnAuthorization(), ajoutez une instruction if autour du reste du code qui vérifie si Threading.Thread.CurrentPrincipal. Identity.IsAuthenticated. De cette façon, l'utilisateur est dirigé vers la page AccessDenied à moins que l'utilisateur ne soit pas authentifié ... dans ce cas, il fera l'action par défaut (rediriger vers la page de connexion) – Frinavale

+0

où cette classe est-elle placée? dans le contrôleur? – Jay

8

Jetez un oeil à tvanfosson « s Answer de this very similar question, ce que je fais (Merci à tvanfosson), maintenant je viens de dire:

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

Si l'utilisateur n'est pas dans le rôle, il obtiendra la vue thew spécifiée par ViewName.

22

Voici ma solution, basée sur la réponse d'eu-ge-ne. Le mien redirige correctement l'utilisateur vers la page de connexion s'il n'est pas connecté, mais vers une page Accès refusé s'il est connecté mais n'est pas autorisé à afficher cette page.

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

vues/compte/Denied.cshtml: (syntaxe Razor)

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

<h2>@ViewBag.Title</h2> 

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

Modification parfaite de la réponse acceptée, merci mon frère –

6

Une légère amélioration à la réponse de Matt b y évitant la nécessité de coder en dur la page d'ouverture de session et éventuellement le réglage de la vue d'accès refusée dans l'attribut:

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

J'ai construit sur la réponse de Vic pour me permettre d'avoir une page Refusé d'accès différent pour chacune des zones de l'application. Est-ce en retournant un RedirectToRouteResult au lieu, qui, au lieu de rediriger vers une URL par rapport à la racine de l'application redirige vers le contrôleur et l'action de la zone actuelle:

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

Juste une petite mise à jour Vic Alcazar, détails Ajouté de l'URL de la requête en redirection cela peut donc enregistrer les détails de l'accès refusé et par qui se veulent

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

Redirect est pas toujours la meilleure solution

utilisation stan dard code http 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden); 
Questions connexes