Обработка безопасности записи/уровня сущности в приложении ASP.NET MVC

Что все делают для обработки безопасности (поиска и изменения) отдельных записей в приложении ASP.NET MVC? Это приложение имеет уровень Service/Business и уровень доступа к данным, которые полностью отделены от пользовательского интерфейса Web. Я уже использую поставщики членства и ролей для проверки подлинности и авторизации для определенных областей/функций в моем приложении, но теперь мне нужно защитить отдельные записи.

Например, скажем, Боб может создавать и редактировать собственные записи FooBar. Я хочу, чтобы другие пользователи не могли просматривать или редактировать записи Боба. Я хочу защитить от манипулирования URL-адресами и/или ошибок программирования. Мы также можем разрешить Бобу делиться своими FooBars с другими пользователями, позволяя им просматривать, но не редактировать свои записи.

Есть несколько подходов, которые я придумал:

  • Выполняйте проверки безопасности на уровне доступа к данным непосредственно в запросах поиска и изменения.
  • Проверьте безопасность на уровне сервиса, выполняя дополнительные запросы безопасности, прежде чем приступать к бизнес-логике.
  • Создайте уровень безопасности, который существует между пользовательским интерфейсом и уровнем сервиса. Пользовательский интерфейс выполнит все запросы через уровень безопасности.
  • Используйте аспектно-ориентированное программирование (АОП). Создайте аспекты безопасности и украсьте методы уровня сервиса атрибутами безопасности.

Я сделал безопасность на уровне доступа к данным (в запросах) в предыдущих проектах, и он всегда превращается в беспорядок. Я хотел бы знать, что делают все остальные, и какие рамки вы используете, чтобы помочь вам (рамки AOP.)

Ответы

Ответ 1

Я всегда принимаю 2-й и/или 3-й из ваших подходов - явный уровень безопасности где-то между пользовательским интерфейсом и логическими обработчиками.

AOP звучит как способ полностью потерять контроль над кодом, а безопасность в DAL звучит как неправильный подход, поскольку он смешивает различные обязанности.

Ответ 2

Я думаю, что повсеместное применение логики может быть проблемой. У меня такая же ситуация. Позвольте мне объяснить, как я его обрабатываю.

public class FooBarController : Controller
{

    //this is easy as compared to edit
    [Authorized]
    public ActionResult Create()
    {


    }


    [AjaxAuthorize(Roles = "Administrator")]    
    public ActionResult Edit(int id)
    {


    }
}

public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {


        var id = filterContext.RouteData.Values["id"];
        // Here you can check if the id belongs to logged in user
        var content = SomeRepository.GetById(id);
        if (contet.OwnerId=LoggedInUser.Id)
           return;

        //otherwise check if logged in user is from some Admin or other role.


        string redirectPage = "/account/logon";
        var roles = base.Roles.Trim().Split(',');
        bool CanAccess = false;

        //If no role is there
        if (base.Roles.Equals(string.Empty) || roles.Count() == 0)
        {
            CanAccess = true;
        }
        else
        {
            foreach (var item in roles)
            {
                CanAccess = filterContext.HttpContext.User.IsInRole(item);
                if (CanAccess)
                    break;
            }
        }

        var request = filterContext.RequestContext.HttpContext.Request;
        if (request.IsAjaxRequest())
        {
            if (!(request.IsAuthenticated && CanAccess))
            {
                filterContext.Result = new AjaxAwareRedirectResult(redirectPage);
                return;
            }
        }

        base.OnAuthorization(filterContext);
    }
}

public class AjaxAwareRedirectResult : RedirectResult
{
    public AjaxAwareRedirectResult(string url)
        : base(url)
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
        {

            string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);

            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "window.location='" + destinationUrl + "';"
            };
            result.ExecuteResult(context);
        }
        else
            base.ExecuteResult(context);
    }
}

Теперь вы можете разрешить редактирование контента либо владельцем, либо администратором. Я называю этот атрибут Ajax, потому что он будет обрабатывать AjaxRequest. Надеюсь, это поможет.

Привет

Parinder

Ответ 3

public class Entity
{
     public Right[] Rights { get; set; }         
}

public class Right
{
     public User user {get;set;}
     public Permission[] permissions {get;set;}

}

public class Foo : Entity
{


}

public class Bar : Entity
{

}

В приведенном выше подходе имеется базовый класс Entity, который сохраняет права, которые определенный пользователь имеет над этим объектом. Наследуйте все классы, которые вы хотите защитить от класса Entity.