2009-08-14 7 views
28

ich eine benutzerdefinierte Rolle Provider zu schaffen und ich setzen ein Autorisieren Attribut eine Rolle in meinem Controller spezifiziert und es funktioniert ganz gut, wie folgt aus:ASP.NET MVC auf einen Zugriff verweigert Seite mit einem benutzerdefinierten Rollenanbieter umleiten

[Authorize(Roles="SuperAdmin")] 
public class SuperAdminController : Controller 
... 

Wenn ein Benutzer jedoch keinen Zugriff auf diesen Controller hat, wird er zur Anmeldeseite umgeleitet. Wie kann ich ihn auf eine "AcessDenied.aspx" Seite umleiten?

Antwort

42
[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"); 
     } 
    } 
} 
+6

Wenn der Benutzer angemeldet ist und versucht, auf die Seite zuzugreifen, werden sie auf die AccessDenied-Seite umgeleitet. Gut. Wenn der Benutzer jedoch nicht angemeldet ist, wird er zur Seite "Zugriff verweigert" weitergeleitet. Schlecht.In diesem Fall sollten sie auf die Anmeldeseite umgeleitet werden. –

+3

Wenn Sie möchten, dass die Seite normal weitergeleitet wird, wenn der Benutzer nicht mehr vorhanden ist, fügen Sie nach dem Aufruf der Methode base.OnAuthorization() eine if-Anweisung um den Rest des Codes hinzu, der prüft, ob Threading.Thread.CurrentPrincipal. Identity.IsAuthenticated. Auf diese Weise wird der Benutzer auf die AccessDenied-Seite geleitet, es sei denn, der Benutzer wird nicht authentifiziert ... in diesem Fall wird die Standardaktion ausgeführt (Weiterleitung zur Anmeldeseite) – Frinavale

+0

Wo wird diese Klasse abgelegt? in der Steuerung? – Jay

8

Werfen Sie einen Blick auf tvanfosson ‚s Answer von this very similar question, Das ist, was ich (Dank Tvanfosson) tue, so sage ich jetzt muss nur:

[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")] 
public class SuperAdminController : Controller 
... 

Wenn der Benutzer nicht in der Rolle ist, erhalten sie die von ViewName angegebene Ansicht.

22

Hier ist meine Lösung, basierend auf eu-ge-ne's Antwort. Mine leitet den Benutzer korrekt zur Anmeldeseite um, wenn er nicht angemeldet ist, aber zu einer Seite mit Zugriffsverweigerung, wenn er angemeldet ist, aber nicht berechtigt ist, diese Seite anzuzeigen.

[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(); 
} 

Views/Account/Denied.cshtml: (Razor-Syntax)

@{ 
    ViewBag.Title = "Access Denied"; 
} 

<h2>@ViewBag.Title</h2> 

Sorry, but you don't have access to that page. 
+1

Perfekte Modifikation von der angenommenen Antwort, danke Bro –

6

eine leichte Verbesserung von Matts Antwort b y Vermeidung der Notwendigkeit einer festen Code der Anmeldeseite und optional den Zugriff verweigert Ansicht innerhalb der Attributeinstellung:

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

ich auf Vic Antwort gebaut haben, mir zu erlauben für einen anderen Zugriff verweigert Seite zu haben, jeden Bereich der Anwendung. Hat es durch ein RedirectToRouteResult anstelle der Rückkehr, die stattdessen auf eine URL relativ zum Stamm der Anwendung der Umleitung es auf den aktuellen Bereich der Controller und die Aktion leitet:

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

Nur ein kleines Update zu Vic Alcazar, Added Details der Anforderungs-uRL in Redirect log das kann also die Einzelheiten der Zugriff verweigert und durch die, wenn

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

Redirect wollen nicht immer die beste Lösung ist

Verwendung stan dard http-code 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden);