web-dev-qa-db-fra.com

Rediriger vers une autre page lorsque l'utilisateur n'est pas autorisé dans asp.net mvc3

J'ai lu 

Comment rediriger facilement si non authentifié dans MVC 3? et Redirige vers la page AccessDenied lorsque l'utilisateur n'est pas autorisé mais le lien à partir d'une réponse (signifie http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your -controller-actions/ ) ne fonctionne pas.

Je mets

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

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

 ....
    }

Et dans mon web.config, j'ai déjà

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

en conséquence avec https://stackoverflow.com/a/6770583/998696

Mais lorsque je veux accéder à /RestrictedPage/Index, il doit me rediriger vers une autre page (depuis un autre contrôleur). Au lieu de cela, l'erreur ressemble à ceci:

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

Avant la connexion, le formulaire de page Logon apparaît correctement, mais l'erreur ci-dessus apparaît lors de l'accès à la page /RestrictedPage/Index. Je peux me connecter avec un autre utilisateur autorisé à accéder à la page RestrictedPage.

Où est mon erreur et comment rediriger l'installation?

19
Snake Eyes

L'attribut par défaut Authorize se comporte de telle manière que, lorsque l'utilisateur est non authentifié ou authentifié mais non autorisé, il définit le code d'état comme 401 (UnAuthorized) . Lorsque le filtre définit le code d'état sur 401 , le framework ASP.NET vérifie si l'authentification par formulaire est activée sur le site Web et si elle est ensuite redirigée vers le paramètre loginUrl défini à cet emplacement.

Si vous voulez changer ce comportement, dites que vous voulez rediriger l'utilisateur vers un contrôleur AccessDenied si l'utilisateur est authentifié mais non autorisé, vous devez étendre l'attribut Authorize et remplacer la méthode HandleUnauthorizedRequest.

Par ex.

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

Vous pouvez remplacer la HandleUnauthorizedRequest selon vos besoins, puis vous devez marquer les actions du contrôleur pour utiliser l'attribut CustomAuthorize au lieu de l'attribut intégré.

52
VJAI

J'aime la réponse de Mark, 
mais je ne veux pas changer tous mes attributs d'action
de [Authorize] à [CustomAuthorize]

J'édite l'action Login() sur AccountController
et vérifiez Request.IsAuthenticated avant la vue du spectacle
Je pense que si l'utilisateur authentifié va à /Account/Logon
Je vais rediriger vers /Error/AccessDenied.

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

        ViewBag.ReturnUrl = returnUrl;

        return View();
    }
3
Yuthasak

Placez "/ Compte/LogOn" au lieu de "~/Compte/LogOn"

2
karaxuna

Oui, c'est correct comme vous l'avez mentionné dans web.config

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

la redirection est à la recherche du contrôleur de compte et de l'action Action de LogOn. Si vous souhaitez rediriger votre page, modifiez-le à la place du compte et connectez-vous.

1
manny

Puisque je ne voulais pas écraser AuthorizeAttribute j'ai utilisé le filtre

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;

    }
}
0
Riddik