ASP.NET MVC中基于文档的安全性

我已经了解ASP.NET MVC中的用户和基于角色的安全性。 但现在我需要一些更精细的东西。

假设我有一份文档列表,其中一些是用户授权的,有些则不是。 每个文档在数据库的文档表中都有相应的记录。 如果用户具有安全访问权限,则可以下载文档以供查看。 如果您有角色,也可以添加文档。 每个文档都有一个URL,每个文档列表都有一个URL。

我想安全修整列表,以便用户只能看到他授权的那些文档。 但是我还需要对这些列表和文档的URL请求进行身份validation,因为没有什么可以阻止用户为他们不再有权访问的文档添加书签,或者只是在浏览器中键入URL。

内置的基于角色的安全模型是否适用于此,或者我是否需要创建单独的基于表的安全性? 我可以将安全性放在我的存储库中,以便返回的记录已被修剪,或者它应该是控制器的一部分吗? 我是否需要安全属性来validation控制器请求,或者我应该将它作为前几行代码放在控制器方法中?

@Robert,我认为你已经回答了自己的问题,当你说你应该修剪它们(之前)到达视野时。 所以在你的业务逻辑中,作为对存储库的偏好,你可能想要做一个lamda来修剪掉多余的东西。

我的意见我永远不会将任何记录返回到用户不被允许看到的视图。 为什么要增加风险和流量?

至于书签,我认为你需要做一些业务逻辑,防止他们在访问不再存在时进入url。

我认为控制器只是为了将数据提供给页面而没有任何逻辑,所以我更喜欢业务层方法,因为它看起来像是一个业务规则。

这可能不是你想到的,但除非有更好的方法,否则我会使用它。

我将尝试解释我打算如何在我的项目中实现它。 该要求与您的要求类似:用户拥有具有权限的角色,所有内容都可以从权限定义,角色权限列表和用户角色列表等进行更改。因此,如果管理员更改,用户可以在一个时刻访问某些内容什么,他没有访问权限。

在我提出一些代码之前,我会回答你的问题。

我是否需要创建单独的基于表的安全性?

-是

我可以将安全性放在我的存储库中,以便返回的记录已被修剪,或者它应该是控制器的一部分吗?

– 我认为安全应该是业务逻辑的一部分,所以我会把它放在控制器和存储库之间。

我是否需要安全属性来validation控制器请求?

– 在我的项目中,我把它放在属性中,但有时我需要从控制器访问它,但是由于我将安全逻辑保留在业务层,我不认为这是一个问题。

第一个属性是简单属性,只允许记录用户执行操作:

public class LoggedUserFilterAttribute : ActionFilterAttribute { public bool Logged { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!SessionManager.IsUserLogged) { filterContext.Result = new RedirectToRouteResult(GetRedirectToNotLoggedRouteValues()); this.Logged = false; } else this.Logged = true; } public RouteValueDictionary GetRedirectToNotAuthorizedRouteValues() { RouteValueDictionary routeValues = new RouteValueDictionary(); routeValues.Add("action", "NotAuthorized"); routeValues.Add("controller", "Authorization"); return routeValues; } public RouteValueDictionary GetRedirectToNotLoggedRouteValues() { RouteValueDictionary routeValues = new RouteValueDictionary(); routeValues.Add("action", "NotLogged"); routeValues.Add("controller", "Authorization"); return routeValues; } } 

然后,我有一个属性,只允许超级用户访问它:

 public class SuperUserFilterAttribute : LoggedUserFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if (Logged) { MyBaseController controller = filterContext.Controller as MyBaseController; if (controller == null) throw new Exception("Please use MyBaseController instead of built in Controller"); User loggedUser = controller.Model.UserBO.GetUserByID(SessionManager.LoggedUser.UserID); if(!loggedUser.IsSuperUser) { filterContext.Result = new RedirectToRouteResult(GetRedirectToNotAuthorizedRouteValues()); } } } } 

MyBaseController是inheritanceController的类,它有一个Model类实例,表示业务对象的容器。 在控制器动作体中,如果需要,我检查当前实体的用户权限,并根据我返回正确的视图:

  [LoggedUserFilter] public ActionResult LoadSomeEntity(int customerServiceID,int entityID) { UserRights userPermissionsView = Model.SecurityBO.GetUsersRightsOnEntity(SessionManager.LoggedUser.UserID, entityID); if(userPermissionsView.Write) return View("EditEntity",Model.EntityBO.GetEntityByID(entityID)); if(userPermissionsView.Read) return View("ViewEntity",Model.EntityBO.GetEntityByID(entityID)); return View("NotAuthorized"); } 

ps我不确定我是否可以向那些显然有更多经验的人推荐任何东西:),所以如果我发送垃圾邮件,我为此道歉。