webentwicklung-frage-antwort-db.com.de

Weiterleiten auf eine andere Seite, wenn der Benutzer in asp.net mvc3 nicht autorisiert ist

Ich habe gelesen 

Wie einfach umleiten, wenn nicht in MVC 3 authentifiziert? und Umleitung zur AccessDenied-Seite, wenn der Benutzer nicht autorisiert ist aber der Link aus einer Antwort (bedeutet http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your -controller-actions/ ) funktioniert nicht.

Ich setze

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

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

 ....
    }

Und in meiner web.config habe ich schon

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

entsprechend mit https://stackoverflow.com/a/6770583/998696

Wenn ich jedoch auf /RestrictedPage/Index zugreifen möchte, muss es mich auf eine andere Seite (von einem anderen Controller) umleiten. Stattdessen sieht der Fehler folgendermaßen aus:

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

Vor dem Anmelden wird das Seitenformular "Logon" korrekt angezeigt. Beim Zugriff auf die Seite "/RestrictedPage/Index" wird jedoch der obige Fehler angezeigt. Ich kann mich mit einem anderen Benutzer einloggen, der zum Zugriff auf die Seite RestrictedPage berechtigt ist.

Wo liegt mein Fehler und wie richten Sie die Umleitung ein?

19
Snake Eyes

Das Standardattribut Authorize verhält sich so, dass, wenn der Benutzer nicht authentifiziert oder authentifiziert, aber nicht autorisiert ist, der Statuscode als 401 (UnAuthorized) gesetzt wird. Wenn der Filter den Statuscode als 401 festlegt, überprüft das ASP.NET-Framework, ob für die Website die Formularauthentifizierung aktiviert ist und ob dann an den dort eingerichteten loginUrl-Parameter umgeleitet wird.

Wenn Sie dieses Verhalten ändern möchten, sagen Sie, dass Sie den Benutzer an einen AccessDenied-Controller umleiten möchten, wenn der Benutzer authentifiziert, aber nicht autorisiert ist. Dann müssen Sie das Attribut Authorize erweitern und die Methode HandleUnauthorizedRequest überschreiben.

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

Sie können die Variable HandleUnauthorizedRequest je nach Bedarf überschreiben. Anschließend müssen Sie die Controller-Aktionen markieren, um das Attribut CustomAuthorize anstelle des integrierten Attributs zu verwenden.

52
VJAI

Ich mag die Antwort von Markus, 
Ich möchte jedoch nicht alle meine Aktionsattribute ändern
von [Authorize] bis [CustomAuthorize]

Ich bearbeite die Funktion Login() für AccountController
und überprüfen Sie Request.IsAuthenticated vor der Showansicht
Ich denke, wenn der authentifizierte Benutzer zu /Account/Logon geht, 
Ich werde zu /Error/AccessDenied umleiten.

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

        ViewBag.ReturnUrl = returnUrl;

        return View();
    }
3
Yuthasak

Platzieren Sie "/ account/logOn" anstelle von "~/account/logOn"

2
karaxuna

Ja, es ist richtig, wie Sie es in der web.config erwähnt haben

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

die Umleitung sucht nach Account-Controller und LogOn-Aktionsergebnis. Wenn Sie Ihre Seite umleiten möchten, wechseln Sie dort anstelle von Konto und Anmeldung

1
manny

Da ich AuthorizeAttribute nicht überschreiben wollte, habe ich Filter verwendet

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