MVC保护基于用户的数据安全

时间:2009-11-26 00:30:38

标签: asp.net-mvc security

我开始涉足ASP.Net MVC。我遇到的一个问题是保护用户数据的最佳做法。例如,在销售人员的场景中,他们应该只能查看自己的数据。

e.g。

SalesData/Edit/14

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

此时,我正在考虑在我的控制器中检查谁登录,并检查他们是否可以访问被请求的“id”。我看到的问题是,这将是应用程序范围,我正在寻找如何处理这个问题的最佳实践。我应该看看CustomControllers吗?过滤器?或者是什么?任何有关如何解决这个问题的文章/参考资料都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

设置从数据库存储库中检索数据的方法,使您可以将当前登录人员的UserID作为参数传递。然后,您可以使用权限表将数据过滤为仅供用户访问的数据。

权限表包含两个字段:UserIDContentID。设置完成后,设置CRUD屏幕非常简单,以便拥有管理权限的人可以设置内容权限。

答案 1 :(得分: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();
    }
}

答案 2 :(得分:0)

我使用IPrincipal和Authorize(Roles ='...')属性来限制对操作的访问。然后将IPrincipal注入服务层,用户IIdentity用于过滤数据。

示例:用户创建任务。每个用户都可以看到他的任务。 GetTask(int taskId)方法首先使用来自IIdentity的标识符通过CreatedBy字段过滤,然后使用指定的id获取任务。如果用户无权访问数据,则方法不会返回任何行。