Comment pouvons-nous définir une autorisation pour toute une zone dans ASP.NET MVC?

J’ai une zone d’administration et je veux que seuls les administrateurs entrent dans la zone. J’ai envisagé d’append l’atsortingbut Authorized à chaque contrôleur de la zone Admin. N’y a-t-il pas une solution élégante ou cette fonctionnalité n’existe pas dans le cadre même?

EDIT: Je suis désolé, j’aurais dû le mentionner avant. J’utilise un AuthorizedAtsortingbute personnalisé dérivé de AuthorizeAtsortingbute.

La sécurité basée sur Web.config ne devrait presque jamais être utilisée dans une application MVC. La raison en est que plusieurs URL peuvent potentiellement toucher un contrôleur, et placer ces vérifications dans Web.config manque toujours quelque chose. Rappelez-vous – les contrôleurs ne sont pas associés à des zones, les itinéraires sont associés à des zones. La fabrique de contrôleurs MVC se fera un plaisir de servir les contrôleurs à partir du dossier Areas / pour les demandes hors zone s’il n’ya pas de conflit.

Par exemple, en utilisant la structure de projet par défaut, en ajoutant une zone Admin avec AdminDefaultController, vous pouvez accéder à ce contrôleur via / Admin / AdminDefault / Index et / AdminDefault / Index.

La seule solution prise en charge consiste à placer votre atsortingbut sur une classe de base de contrôleur et à vous assurer que chaque contrôleur de la zone sous-classe cette classe de base.

Je viens d’enquêter sur ce même problème. Comme il n’est pas possible de sécuriser les contrôleurs en fonction des zones, une option plus simple apparaît.

Créez une définition de contrôleur de base pour chaque zone qui remplace le contrôleur et ajoutez à cela la sécurité requirejse. Il vous suffit ensuite de vous assurer que chaque contrôleur de la zone remplace AreaController au lieu de Controller. Par exemple:

///  /// Base controller for all Admin area ///  [Authorize(Roles = "Admin")] public abstract class AdminController : Controller { } 

Il faut toujours dériver chaque contrôleur dans la zone Admin de cette base,

 public class HomeController : AdminController { // .. actions } 

mais au moins vous avez un seul point où vous définissez la sécurité pour la zone.

Si tout votre code administrateur est dans un seul contrôleur, ajoutez Autoriser à la classe entière.

 [Authorize] public class AdminController : Controller { ....... } 

Je viens juste de commencer… mais jusqu’à présent, cela fonctionne plutôt bien pour moi.

Je crée une classe AuthorizeAtsortingbute personnalisée et l’ajoute dans la fonction RegisterGlobalFilters.

Dans CustomAuthorizeAtsortingbute, je vérifie les différentes conditions en fonction de la zone dans laquelle il se trouve.

 public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomAuthorizeAtsortingbute()); filters.Add(new HandleErrorAtsortingbute()); } } public class CustomAuthorizeAtsortingbute : AuthorizeAtsortingbute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var routeData = httpContext.Request.RequestContext.RouteData; var controller = routeData.GetRequiredSsortingng("controller"); var action = routeData.GetRequiredSsortingng("action"); var area = routeData.DataTokens["area"]; var user = httpContext.User; if (area != null && area.ToSsortingng() == "Customer") { if (!user.Identity.IsAuthenticated) return false; } else if (area != null && area.ToSsortingng() == "Admin") { if (!user.Identity.IsAuthenticated) return false; if (!user.IsInRole("Admin")) return false; } return true; } } 

La réponse actuellement acceptée n’est pas la solution la plus sécurisée, car elle oblige le développeur à toujours hériter de cette nouvelle classe de base pour les nouveaux contrôleurs ou actions (“blacklisting”, autorisant les utilisateurs à accéder à moins qu’une action ne soit restreinte manuellement). Cela pose surtout des problèmes lorsque de nouveaux développeurs, qui ne connaissent pas vos rituels, sont initiés au projet. Il est facile d’oublier d’hériter de la classe de contrôleur appropriée si cela est fait de cette manière, surtout après avoir quitté le projet pendant des semaines, des mois ou des années. Si un développeur oublie d’hériter, il n’est pas évident qu’il existe une vulnérabilité de sécurité dans le projet.

Une solution plus sûre à ce problème consiste à refuser l’access à toutes les demandes, puis à décorer chaque action avec les rôles autorisés à accéder aux actions («liste blanche»; empêcher l’access à tous les utilisateurs, sauf autorisation manuelle). Maintenant, si un développeur oublie de mettre en liste blanche les permissions appropriées, les utilisateurs vous le feront savoir et c’est aussi simple que de consulter d’autres contrôleurs pour savoir comment donner un access correct. Cependant, au moins, il n’ya pas de vulnérabilité majeure en matière de sécurité.

Dans le fichier App_Start / FilterConfig.cs, modifiez la classe FilterConfig:

 public static void RegisterGlobalFilters(GlobalFilterCollection filters) { ... //Deny access to all controllers and actions so that only logged in Administrators can access them by default filters.Add(new System.Web.Mvc.AuthorizeAtsortingbute() { Roles = "Administrator" }); } 

Cela rend toutes les actions inaccessibles, sauf si l’utilisateur est connecté en tant qu’administrateur. Ensuite, pour chaque action à laquelle un utilisateur autorisé différent doit avoir access, il vous suffit de le décorer avec [OverrideAuthorization] et [Authorize] .

Dans votre logique métier, cela vous permet d’utiliser l’atsortingbut Authorize de différentes manières sans avoir à vous soucier de l’access à des fonctionnalités par des utilisateurs non autorisés. Voici quelques exemples.

Exemple 1 – Seuls les utilisateurs connectés Administrateur et Dispatcher seront autorisés à accéder aux méthodes Get et Post d’ Index() .

 public class MarkupCalculatorController : Controller //Just continue using the default Controller class. { // GET: MarkupCalculator [OverrideAuthorization] [Authorize(Roles = "Administrator,Dispatcher")] public ActionResult Index() { //Business logic here. return View(...); } // POST: DeliveryFeeCalculator [HttpPost] [ValidateAntiForgeryToken] [OverrideAuthorization] [Authorize(Roles = "Administrator,Dispatcher")] public ActionResult Index([Bind(Include = "Price,MarkedupPrice")] MarkupCalculatorVM markupCalculatorVM) { //Business logic here. return View(...); } } 

Exemple 2 – Seuls les utilisateurs authentifiés seront autorisés à accéder à la méthode Index() du contrôleur Index() .

 public class HomeController : Controller { [OverrideAuthorization] [Authorize] //Allow all authorized (logged in) users to use this action public ActionResult Index() { return View(); } } 

Exemple 3 – Les utilisateurs non authentifiés (utilisateurs anonymes) peuvent être autorisés à accéder aux méthodes en utilisant l’atsortingbut [AllowAnonymous] . Cela remplace également automatiquement le filtre global sans avoir besoin de l’atsortingbut [OverrideAuthorization] .

  // GET: /Account/Login [AllowAnonymous] public ActionResult Login(ssortingng returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); } // // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task Login(LoginViewModel model, ssortingng returnUrl) { ... } 

Exemple 4 – Seuls les administrateurs seront autorisés à accéder aux méthodes dépourvues de l’atsortingbut [Authorize] .

 public class LocationsController : Controller { // GET: Locations public ActionResult Index() { //Business logic here. return View(...); } } 

Quelques notes.

Vous devez utiliser l’atsortingbut [OverrideAuthorization] si vous souhaitez limiter l’access à une action particulière à des rôles spécifiques. Sinon, les propriétés de l’atsortingbut [Authorize] seront ignorées et seul le rôle par défaut (Administrator dans mon exemple) sera autorisé, même si vous spécifiez d’autres rôles (par exemple Dispatcher, etc.) en raison du filtre global. Tout utilisateur non autorisé sera redirigé vers l’écran de connexion.

L’utilisation de l’atsortingbut [OverrideAuthorization] entraîne que l’action ignore le filtre global défini. Par conséquent, vous devez réappliquer l’atsortingbut [Authorize] chaque fois que vous utilisez le remplacement pour que l’action rest sécurisée.

Concernant les zones entières et les contrôleurs

Pour limiter les zones, comme vous le demandez, placez les atsortingbuts [OverrideAuthorization] et [Authorize] sur le contrôleur au lieu des actions individuelles.

.. très cruellement je crois que vous voulez quelque chose comme ça?

Gestion des rôles rapide et sale

 [Authorize(Roles = "Admins")] public ActionResult Register() { ViewData["roleName"] = new SelectList(Roles.GetAllRoles(), "roleName"); ViewData["PasswordLength"] = MembershipService.MinPasswordLength; return View(); }