我们如何在ASP.NET MVC中设置整个区域的授权?

我有一个pipe理员区域,我只想要pipe理员进入该区域。 我考虑将“授权”属性添加到“pipe理”区域中的每个控制器。 是不是有一个优雅的解决scheme,或者这个function没有在框架本身?

编辑:对不起,我应该提前这个。 我正在使用派生自AuthorizeAttribute的自定义AuthorizedAttribute。

基于Web.config的安全性应该几乎不会在MVC应用程序中使用。 原因是多个URL可能会碰到一个控制器,并且在Web.config中放置这些检查总是会漏掉一些东西。 请记住,控制器不与区域相关联,path与区域相关联。 如果没有冲突,MVC控制器工厂将非常乐意地为区域/文件夹服务于非区域请求的控制器。

例如,使用默认的项目结构,添加一个AdminDefaultController的Admin区域,您可以通过/ Admin / AdminDefault / Index / AdminDefault / Index命中这个控制器。

唯一受支持的解决scheme是将您的属性放在控制器基类上,并确保该区域内的每个控制器inheritance该基类。

我刚刚正在调查这个相同的问题。 由于不能根据区域来保护控制器,因此想到更简单的选项。

为覆盖Controller的每个区域创build一个基本控制器定义,并将安全要求添加到此处。 然后,您只需确保区域中的每个控制器都会覆盖AreaController而不是Controller。 例如:

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

它仍然要求你从这个基地派生pipe理区域的每个控制器,

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

但是至less你有一个单独的点来定义该区域的安全性。

如果您的所有pipe理员代码都在一个控制器中,则将授权添加到整个class级。

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

我刚刚开始这个…但是到目前为止,这对我来说是非常好的。

我创build一个自定义的AuthorizeAttribute类,并将其添加到RegisterGlobalFilters函数中。

在CustomAuthorizeAttribute中,我根据它所在的区域来检查各种条件。

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

目前接受的答案并不是最安全的解决scheme,因为它要求开发人员始终记住为任何新的控制器或操作(“黑名单”;允许用户访问所有内容,除非手动限制操作)inheritance新的基类。 如果不熟悉您的仪式的新开发人员被介绍到项目中,这尤其会造成问题。 如果这样做的话,忘记inheritance适当的控制器类是很容易的,特别是在把眼睛从项目上拖了几周,几个月或几年之后。 如果开发人员忘记inheritance,那么项目中存在安全漏洞并不明显。

解决此问题的更安全的方法是拒绝对所有请求的访问,然后使用允许访问操作的angular色(“白名单”;阻止对所有用户的访问,除非手动允许)来修饰每个操作。 现在,如果开发人员忘记了正确授权的白名单,用户将会通知您,并且像查看其他控制器一样简单,提醒您如何正确访问。 但是,至less没有重大的安全漏洞。

在App_Start / FilterConfig.cs文件中,修改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.AuthorizeAttribute() { Roles = "Administrator" }); } 

这使得所有操作都无法访问,除非用户以pipe理员身份login。 然后,对于您希望获得其他授权用户访问的每个操作,只需使用[OverrideAuthorization][Authorize]对其进行修饰即可。

在您的业务逻辑中,这允许您以各种方式使用Authorize属性,而无需担心未经授权的用户访问任何function。 以下是一些例子。

示例1 – 只有loginpipe理员和分派器的用户才可以访问Index() Get和Post方法。

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

示例2 – 只有经过身份validation的用户将被允许访问主控制器的Index()方法。

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

示例3 – 可以通过使用[AllowAnonymous]属性来允许未经身份validation的用户(即匿名用户)访问方法。 这也会自动覆盖全局filter,而不需要[OverrideAuthorization]属性。

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

示例4 – 只有pipe理员才能访问缺less[Authorize]属性的方法。

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

一些笔记。

如果要将对特定操作的访问限制为特定angular色,则必须使用[OverrideAuthorization]属性。 否则,即使由于全局filter而指定了其他angular色(例如Dispatcher等),“ [Authorize]属性属性也将被忽略,只有默认angular色(在我的示例中为Administrator)将被允许。 任何未经授权的用户将被redirect到login屏幕。

使用[OverrideAuthorization]属性会导致该操作忽略您设置的全局filter。 因此,无论何时使用覆盖,都必须重新应用[Authorize]属性,以便操作保持安全。

关于整个地区和pipe制员

要按区域进行限制,请按照要求将[OverrideAuthorization][Authorize]属性放在控制器上,而不是单个操作。

..很粗鲁,我相信你想要这样的东西?

快速和肮脏的angular色pipe理

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