ASP.NET MVC rediriger vers une page à Accès refusé en utilisant un fournisseur de rôle personnalisé
je crée un fournisseur de rôle personnalisé et j'ai défini un attribut D'autorisation spécifiant un rôle dans mon contrôleur et cela fonctionne très bien, comme ceci:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
mais quand un utilisateur n'a pas accès à ce contrôleur, il est redirigé vers la page de connexion. Comment puis-je le rediriger vers un "AcessDenied"?aspx" page?
8 réponses
[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");
}
}
}
voici ma solution, basée sur la réponse d'eu-ge-ne. Mine 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é à voir 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/Refusé.cshtml: (syntaxe Razor)
@{
ViewBag.Title = "Access Denied";
}
<h2>@ViewBag.Title</h2>
Sorry, but you don't have access to that page.
jetez un oeil à tvanfosson 's réponse de cette question très similaire , C'est ce que je fais(grâce à tvanfosson), donc maintenant je dois juste dire:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...
si l'utilisateur n'est pas dans le rôle, il obtiendra la vue W spécifiée par ViewName.
une légère amélioration à la réponse de Matt en évitant la nécessité de coder la page de connexion et en configurant optionnellement la vue Accès refusé 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);
}
}
}
Redirection n'est pas toujours la meilleure solution
utiliser le code standard http 403:
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
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");
}
}
}
j'ai construit sur la réponse de Vic pour me permettre d'avoir une page D'Accès refusé différente pour chacun des domaines de la demande. L'a fait en retournant un RedirectToRouteResult
à la place, qui au lieu de rediriger vers une URL relative à la racine de l'application il redirige vers le contrôleur de la zone actuelle et l'action:
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 }));
}
}
}
juste une petite mise à jour pour Vic Alcazar, Ajout de détails sur l'url de la requête dans redirect Ainsi, cela peut enregistrer les détails de l'Accès refusé et par qui si vous voulez
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));
}
}
}