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?
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é.
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();
}
Placez "/ Compte/LogOn" au lieu de "~/Compte/LogOn"
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.
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;
}
}