Я попытаюсь объяснить, как я намеревался реализовать это в своем проекте. Требование такое же, как и у вас: у пользователей есть роли, у которых есть разрешения, и все может измениться из определения полномочий, списка разрешений ролей, списка ролей пользователя и т. Д. Поэтому в один момент возможно, что у пользователя есть доступ к чему-либо, а в другом, если администратор изменил что-то, у него нет доступа.
Прежде чем я напишу код, я отвечу на ваши вопросы.
Нужно ли создавать отдельно,
безопасность на основе таблиц?
1009 * Да *
Могу ли я поставить безопасность в моем
хранилище, так что возвращаемый
записи уже обрезаны или должны
это будет частью контроллера?
-Я думаю, что безопасность должна быть частью бизнес-логики, поэтому я бы поместил ее где-то между контроллером и хранилищем.
Нужен ли мне атрибут безопасности для
проверить запрос контроллера?
-В моем проекте я поместил его в атрибут, но иногда мне нужно получить к нему доступ от контроллера к, но с тех пор я сохраняю логику безопасности на бизнес-уровне, я не думаю, что это проблема.
Первый атрибут - это простой атрибут, который позволяет зарегистрированным пользователям выполнять действие:
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;
}
}
и затем у меня есть, например, атрибут, который позволяет только SuperUsers получить к нему доступ:
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 - это класс, который наследует Controller и имеет экземпляр класса 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");
}
p.s. Я не уверен, что могу что-то предложить кому-то, у кого явно больше опыта, чем у меня :), поэтому, если я спамлюсь, прошу прощения за это.