2009-11-26 49 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