Asp.net mvc MVC保护基于用户的数据安全
我开始涉猎ASP.NETMVC。我的一个问题是关于保护用户数据的最佳实践。例如,在销售人员的场景中,他们应该只能查看自己的数据 e、 g 更改“14”以查看他们可能/或可能无法访问的其他数据非常容易Asp.net mvc MVC保护基于用户的数据安全,asp.net-mvc,security,Asp.net Mvc,Security,我开始涉猎ASP.NETMVC。我的一个问题是关于保护用户数据的最佳实践。例如,在销售人员的场景中,他们应该只能查看自己的数据 e、 g 更改“14”以查看他们可能/或可能无法访问的其他数据非常容易 此时,我正在考虑在控制器中检查谁已登录,并检查他们是否有权访问请求的“id”。我看到的问题是,这将是应用程序范围内的,我正在寻找关于如何实现这一点的最佳实践。我应该看看客户控制器吗?过滤器?还是怎样任何关于如何解决这一问题的文章/参考资料都将不胜感激。设置从数据库存储库检索数据的方法,以便您可以将当
此时,我正在考虑在控制器中检查谁已登录,并检查他们是否有权访问请求的“id”。我看到的问题是,这将是应用程序范围内的,我正在寻找关于如何实现这一点的最佳实践。我应该看看客户控制器吗?过滤器?还是怎样任何关于如何解决这一问题的文章/参考资料都将不胜感激。设置从数据库存储库检索数据的方法,以便您可以将当前登录用户的
用户ID作为参数传递。然后,您可以使用权限表将数据筛选到用户有权访问的数据
权限表将有两个字段:UserID
和ContentID
。一旦设置好了,设置CRUD屏幕就相当简单了,这样具有管理权限的人就可以设置内容权限。我使用IPrincipal和Authorize(Roles='…')属性来限制对操作的访问。然后将IPrincipal注入服务层,并使用用户身份来过滤数据
示例:用户创建任务。每个用户都可以看到他的任务。GetTask(int taskId)方法首先使用IIdentity中的标识符按CreatedBy字段进行筛选,然后接受具有指定id的任务。若用户无权访问数据,该方法将不会返回任何行
我看到的问题是
这将是广泛应用的
然后您需要处理它的公共服务。令人惊讶的是,我称之为IauthoritationService
而我
我正在寻找最佳实践方法
来接近这一点。我应该看看吗
在海关控制员那里?过滤器?或
什么
无论您选择哪种方式,您都应该使用上面的通用iAuthorizationService。
根据我的经验,我可以看出将服务注入控制器并在每个操作中使用它更容易:
/* 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();
}
}
类依赖注入容器:WindsorContainer{
公共依赖注入容器(){
RegisterDependencies();
}
私有无效注册表依赖项(){
//服务
登记册(
AllTypes.Of()
.FromAssembly(类型为(IDisCorableService).Assembly)
.Configure(c=>c.lifesture.Transient)
.WithService.FromInterface()
);
//控制器
登记册(
AllTypes.Of()
.FromAssembly(类型(DependencyInjectionContainer).Assembly)
.Configure(c=>c.lifesture.Transient)
);
}
}
WindsorController工厂类:DefaultControllerFactory,IDisposable{
私有只读IWindsorContainer;
公共风管控制器工厂(){
容器=新的DependencyInjectionContainer();
}
受保护的覆盖IController GetControllerInstance(类型controllerType){
如果(controllerType==null)
返回base.GetControllerInstance(controllerType);
返回(IController)容器。解析(controllerType);
}
公共空间处置(){
container.Dispose();
}
}
好建议。Re:权限表,ContentID是什么?假设我有订单、订单项、销售单等。。。许多实体。contentId是什么?我怎么知道这个ID映射了什么呢?在这种情况下,您需要权限表中的另一个字段,即TableID。有一个包含表名和表ID的表也很好。或者,您可以向上移动到用户有权访问的实体,该实体包含有问题的记录。例如,如果销售人员有权访问特定订单,则他也有权访问该订单上的所有OrderItems。查看您的代码,您似乎只指定了“编辑”等角色,而没有指定特定项目的权限。
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();
}
}