web-dev-qa-db-fra.com

Redirection ASP.NET MVC vers une page d'accès refusé à l'aide d'un fournisseur de rôle personnalisé

Je crée un fournisseur de rôle personnalisé et je définis un attribut Authorize spécifiant un rôle dans mon contrôleur. Cela fonctionne parfaitement, comme ceci:

[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"?

29
AndreMiranda
[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");
        }
    }
}
42
eu-ge-ne

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 d'accès refusé s'il est connecté mais non autorisé à le visualiser. 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.
25
Matt Frear

Regardez tvanfosson s Answer de cette question très similaire , c’est ce que je suis en train de faire (Merci à tvanfosson), alors il me suffit 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 spécifiée par ViewName.

8
KP.

La redirection n'est pas toujours la meilleure solution

Utilisez le code HTTP standard 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
6
devi

Une légère amélioration par rapport à la réponse de Matt en évitant d'avoir à coder en dur la page de connexion et en définissant éventuellement la vue d'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);
        }
    }
}
6
Vic Alcazar

J'ai construit sur la réponse de Vic pour me permettre d'avoir une page d'accès refusé différente pour chaque zone de l'application. Je l'ai fait en renvoyant plutôt une RedirectToRouteResult qui, au lieu de rediriger vers une URL relative à la racine de l'application, le redirige vers le contrôleur et l'action de la zone en cours:

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
Farinha

Juste une petite mise à jour de Vic Alcazar, Ajout des détails de l’URL de la demande dans la redirection Afin que les détails de l’accès refusé et ceux qui le souhaitent soient enregistrés. 

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));
        }
    }
}
0
True Solutions
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
Yuriy