2009-11-26 48 views
3

我開始涉足ASP.Net MVC。我有一個問題是保護用戶數據的最佳做法。例如,在銷售人員的情況下,他們應該只能查看他們自己的數據。MVC保護基於用戶的數據安全

例如

SalesData/Edit/14 

這是很容易改變的「14」,以查看他們可能/或可以不具有訪問其他數據。

在這一點上,我想在我的控制器檢查誰登錄,並檢查他們是否有權訪問獲得請求的「ID」。我看到的問題是,這將是應用程序範圍廣泛的,我正在尋找有關如何解決此問題的最佳實踐。我應該看看CustomControllers嗎?過濾器?或者是什麼?任何文章/參考如何解決這個問題將不勝感激。

回答

1

設置您的方法從數據庫存儲庫中檢索數據,以便您可以將當前登錄的UserID作爲參數傳遞。然後,您可以使用權限表將數據過濾爲僅限用戶有權訪問的數據。

權限表將有兩個字段:UserIDContentID。設置完成後,設置CRUD屏幕非常簡單,因此具有管理權限的用戶可以設置內容權限。

+0

好的建議。 Re:權限表,ContentID是什麼?可以說我有Orders,OrderItems,SalesSlips等......很多實體。 contentId是什麼?我怎麼知道那個ID地圖呢? – zzz 2009-11-26 00:49:27

+0

在這種情況下,您需要另一個屬於TableID的權限表中的字段。有一個包含表名和表ID的表也很好。 – 2009-11-26 01:52:14

+0

或者,您可以移動到用戶有權訪問的實體,該實體包含有問題的記錄。例如,如果銷售人員可以訪問特定的訂單,他還可以訪問該訂單上的所有訂單項。 – 2009-11-26 02:00:44

0

我使用IPrincipal和Authorize(Roles ='...')屬性來限制對操作的訪問。然後將IPrincipal注入服務層,並使用用戶IIdentity來過濾數據。

示例:用戶創建任務。每個用戶都可以看到他的任務。 GetTask(int taskId)方法首先使用來自IIdentity的標識符通過CreatedBy字段進行過濾,然後使用指定的標識符獲取任務。如果用戶無權訪問數據,則方法不會返回任何行。

1

我這個看到的問題是, 這將是應用廣泛,

然後,你需要處理它普遍的服務。令人驚訝的是,我將其稱爲IAuthorisationService。

和我 正在尋找有關如何處理此問題的最佳實踐。我應該在CustomControllers看 ?過濾器?或者 是什麼?

無論您選擇哪種方式,都應該使用上面的常見IAuthorisationService。
從我的經驗,我可以告訴大家,它更容易注入服務到控制器,並使用它的每一個動作:

/* Interfaces */ 
public interface IAuthorisationService { 
    bool CanEdit(YourItem item); 
} 

public interface ICurrentUserProvider { 
    YourUserEntity GetCurrentUser(); 
} 

/* Implementations */ 
public class HttpUserProvider : ICurrentUserProvider { 
    public YourUserEntity GetCurrentUser() { 
     return HttpContext.Current.User.Principal as YourUserEntity; 
    } 
} 

public calss RolesAuthorisationService : IAuthorisationService { 
    ICurrentUserProvider userProvider 
    public RolesAuthorisationService(ICurrentUserProvider userProvider) { 
     this.userProvider = userProvider; 
    } 

    public bool CanEdit(YourItem item) { 
     var u = userProvider.GetCurrentUser(); 
     if (u == null) 
      return false; 
     return item.Owner == u && u.IsInRole("EditYourItem"); 
    } 
} 

/* Controller */ 

public class MyController: Controller { 
    IAuthorisationService authorisation; 

    public MyController(IAuthorisationService authorisation) { 
     this.authorisation = authorisation; 
    } 

    public ActionResult Edit(int id) { 
     var item = GetTheItembyIdSomehow(); 
     if (!authorisation.CanEdit(item)) 
      return new HttpUnauthorizedResult(); 

     // Can do this 
    } 
} 

然後你可以使用的ControllerFactory自動注入所需的依賴到控制器:

class DependencyInjectionContainer : WindsorContainer { 
    public DependencyInjectionContainer() { 
     RegisterDependencies(); 
    } 

    private void RegisterDependencies() { 

     // Services 
     Register(
      AllTypes.Of<IDiscoverableService>() 
       .FromAssembly(typeof(IDiscoverableService).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
       .WithService.FromInterface() 
      ); 

     // Controllers 
     Register(
      AllTypes.Of<IController>() 
       .FromAssembly(typeof(DependencyInjectionContainer).Assembly) 
       .Configure(c => c.LifeStyle.Transient) 
      ); 
    } 
} 

class WindsorControllerFactory : DefaultControllerFactory, IDisposable { 
    private readonly IWindsorContainer container; 

    public WindsorControllerFactory() { 
     container = new DependencyInjectionContainer(); 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     if (controllerType == null) 
      return base.GetControllerInstance(controllerType); 
     return (IController) container.Resolve(controllerType); 
    } 

    public void Dispose() { 
     container.Dispose(); 
    } 
} 
+0

看着你的代碼,看起來你只是指定了諸如「編輯」之類的角色,而沒有指定特定項目的權限。 – 2009-11-26 01:54:43

+0

哦。是。抱歉。我會更新它。 – 2009-11-26 02:03:15