2011-11-23 5 views
15

Co każdy robi, aby poradzić sobie z zabezpieczeniami (wyszukiwaniem i modyfikacją) poszczególnych rekordów w aplikacji ASP.NET MVC? Ta aplikacja ma warstwę Service/Business i warstwę Data Access, które są całkowicie oddzielone od interfejsu WWW. Używam już dostawców członkostwa i ról do obsługi uwierzytelniania i autoryzacji dla określonych obszarów/funkcji w mojej aplikacji, ale teraz muszę zabezpieczyć poszczególne rekordy.Zabezpieczenia rekordu/poziomu obiektu w aplikacji ASP.NET MVC

Na przykład powiedz, że Bob może tworzyć i edytować własne zapisy FooBar. Chcę zapewnić, że inni użytkownicy nie będą mogli przeglądać ani edytować wpisów Boba. Chcę chronić przed manipulowaniem adresami URL i/lub błędami w programowaniu. Możemy również chcieć umożliwić Bobowi udostępnianie swoich FooBarów innym użytkownikom, pozwalając im przeglądać, ale nie edytować jego zapisów.

Istnieje kilka podejść I mają pochodzić z:

  • Czy kontrole bezpieczeństwa w warstwie dostępu do danych bezpośrednio w wyszukiwawczych i modyfikacja zapytaniami.
  • Sprawdź zabezpieczenia w warstwie usług, wykonując dodatkowe zapytania bezpieczeństwa przed kontynuowaniem logiki biznesowej.
  • Utwórz warstwę zabezpieczeń istniejącą między interfejsem użytkownika a warstwą usługi. Interfejs użytkownika będzie wykonywać wszystkie żądania za pośrednictwem warstwy zabezpieczeń.
  • Stosuj programowanie aspektowe (AOP). Twórz aspekty bezpieczeństwa i dekoruj metody warstw serwisowych za pomocą atrybutów bezpieczeństwa.

Zrobiłem zabezpieczenia w warstwie dostępu do danych (w zapytaniach) w poprzednich projektach, i zawsze zmienia się w bałagan. Chciałbym wiedzieć, co robią inni i jakie są ramy, których używasz, aby ci pomóc (ramy AOP.)

Odpowiedz

2

Zawsze biorę 2 i 3 z twoich podejść - jawna warstwa bezpieczeństwa gdzieś pomiędzy interfejsem a programy do obsługi logiki.

AOP brzmi jak sposób na całkowitą utratę kontroli nad kodem, a bezpieczeństwo w DAL brzmi jak błędne podejście, ponieważ miesza różne obowiązki.

2

Myślę, że umieszczanie logiki wszędzie może stanowić problem. Mam podobną sytuację. Pozwól mi wyjaśnić, jak sobie z tym radzę.

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

Teraz możesz zezwolić na edycję treści przez właściciela lub administratora. Nazywam ten atrybut jako Ajax, ponieważ będzie obsługiwał także AjaxRequest. Mam nadzieję, że to pomoże.

Pozdrowienia

Parinder

0
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 
{ 

} 

W powyższym podejściem jest klasa podstawowa jednostka, która przechowuje praw dany użytkownik ma nad tym podmiotem. Dziedzicz wszystkie klasy, które chcesz zabezpieczyć przed klasą Entity.