Asp.net mvc MVC保护基于用户的数据安全

Asp.net mvc MVC保护基于用户的数据安全,asp.net-mvc,security,Asp.net Mvc,Security,我开始涉猎ASP.NETMVC。我的一个问题是关于保护用户数据的最佳实践。例如,在销售人员的场景中,他们应该只能查看自己的数据 e、 g 更改“14”以查看他们可能/或可能无法访问的其他数据非常容易 此时,我正在考虑在控制器中检查谁已登录,并检查他们是否有权访问请求的“id”。我看到的问题是,这将是应用程序范围内的,我正在寻找关于如何实现这一点的最佳实践。我应该看看客户控制器吗?过滤器?还是怎样任何关于如何解决这一问题的文章/参考资料都将不胜感激。设置从数据库存储库检索数据的方法,以便您可以将当

我开始涉猎ASP.NETMVC。我的一个问题是关于保护用户数据的最佳实践。例如,在销售人员的场景中,他们应该只能查看自己的数据

e、 g

更改“14”以查看他们可能/或可能无法访问的其他数据非常容易


此时,我正在考虑在控制器中检查谁已登录,并检查他们是否有权访问请求的“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();
    }
}