0

目前我正在用 MVC 4 编写一个 Web 应用程序。我使用的是通用存储库模式。它运作良好。所以我有以下类似的东西,

public class AddressRepository : IAddressRepository
    {
        private AISDbContext context = new AISDbContext();

        public IQueryable<Address> GetAddresses()
        {
            return context.Address;
        }

    }

但是现在我需要添加一些东西来更多地过滤数据。根据登录用户的角色,应该对这些数据进行更多过滤。

像这样的东西..

public IQueryable<Address> GetAddresses()
{
   return context.Address.where(x=>x.haspermissions = CURENTUSER.Role);
 }

现在我总是可以添加另一个这样的功能,但我想尝试一个通用的。我想知道我是否可以只使用第一段代码并从另一个类继承,这只是应用安全修整。这样我就不必重写所有查询,我只需告诉每个类从安全修剪器继承。希望这是有道理的..

谢谢

更新代码

public class AddressRepository : SecureRepositoryBase<Address>, IAddressRepository
    {
        private AISDbContext context = new AISDbContext();

        public IQueryable<Address> GetAll()
        {
            return base.RetrieveSecure(context.Address, 1);           
        }
}

 public abstract class SecureRepositoryBase<T> where T : ISecuredEntity
    {
        public IQueryable<T> RetrieveSecure(IQueryable<T> entities, int currentUser)
        {
            return entities.Where(e => e.InspectorId == currentUser);         
        }
    }

 public interface ISecuredEntity
    {
        int? InspectorId { get; set; }
    }

 public class Address: ISecuredEntity
    {
        public int COESNo { get; set; }
        public int Postcode { get; set; }
        public int AuditAuthNo { get; set; }
        public bool? SelectedForAudit { get; set; }
        public int? RECId { get; set; }
        public string CustomerName { get; set; }
        public string CustomerAddress { get; set; }
        public int? CustomerSuburbId { get; set; }
        public int? InspectorId { get; set; }
        public DateTime? AuditDate { get; set; }
        public int? AuditType { get; set; }
        public int? UploadType { get; set; }
        public string COESImage { get; set; }
        public DateTime CreatedDate { get; set; }
        public int? CreatedBy { get; set; }
        public DateTime? ModifiedDate { get; set; }
        public int? ModifiedBy { get; set; }

        public virtual UserDetails Inspector { get; set; }
        public virtual Postcodes CustomerSuburb { get; set; }
        public virtual ResponsiblePerson RPerson { get; set; }
        public virtual UserProfile CreatedByUser { get; set; }
        public virtual UserProfile ModifiedByUser { get; set; }
    }
4

3 回答 3

0

创建一个基类,将每个查询转换为一个检查权限的查询,并让您的存储库类继承自该查询。

像这样的东西:

public interface ISecuredEntity
{
    IEnumerable<string> Permissions { get; }
}

public class Address : ISecuredEntity
{
    public IEnumerable<string> Permissions { get; set; }
}

public class AddressRepository : SecureRepositoryBase<Address>, IAddressRepository
{
    private AISDbContext context = new AISDbContext();

    public IQueryable<Address> GetAddresses()
    {
        return base.RetrieveSecure(context.Address, CURENTUSER);
    }
}

public abstract class SecureRepositoryBase<T>
    where T : ISecuredEntity
{
    public IQueryable<T> RetrieveSecure(IQueryable<T> entities, IUser currentUser)
    {
        return entities.Where(e => e.Permissions.Contains(currentUser.Role));
    }
}
于 2013-06-14T06:48:29.493 回答
0

您可能想查看全局过滤器。我包括一个简短的例子来说明它是如何工作的:

public class AISDbContext : DbContext
{
    public void ApplyFilters(IList<IFilter<AISDbContext>> filters)
    {
        foreach(var filter in filters)
        {
            filter.DbContext = this;
            filter.Apply();
        }
    }
}

public interface IFilter<T> where T : DbContext
{
    T DbContext {get; set;}
    void Apply();
}

public class AdminRoleFilter : IFilter<AISDbContext>
{
    public AISDbContext _dbContext {get; set;}
    public void Apply()
    {
        _dbContext.Address = new FilteredDbSet(_dbContext, d => d.haspermissions = "Admin");
    }
}

的细节FilteredDbSet非常广泛,可以在这里找到。

然后你的实现DbContextAddressRepository如下所示:

var context = new AISDbContext();
context.ApplyFilters(new List<IFilter<AISDbContext>>()
    {
        new AdminRoleFilter()
    });

public List<Address> GetAddresses()
{
    return context.Address.ToList();
}
于 2013-06-14T13:27:39.443 回答
0

MVC存储库模式,如何安全修剪?

存储库不应该负责访问控制/安全修整。它仅提供查询域对象的方法

在下面的代码中

function GetAddresses() as IQueryable(of Address)
function GetAddressesInspectedBy(Inspector as Inspector) as IQueryable(of Address)

该方法GetAddresses将返回所有可用的地址。

该方法GetAddressesInspectedBy将返回具体检查器检查的所有地址。

这两种方法明显不同,并且在存储库中相互共存。两种方法都应该可用,但是调用什么方法取决于存储库外部的业务逻辑/访问控制。

但是现在我需要添加一些东西来更多地过滤数据。根据登录用户的角色,应该对这些数据进行更多过滤。

返回给用户的数据不应该基于用户的角色!相反,它应该基于用户的要求!并且请求是否可以执行取决于用户的角色。

例如,管理员角色用户可能被允许请求以下各项

  1. 所有地址,
  2. 具体检查员的地址,
  3. 自己检查的地址。

三种请求类型中的每一种都返回不同的结果,独立于管理员角色!

虽然可能只允许检查员角色用户请求

  1. 仅由他自己检查的地址。

应用程序接收请求,检查是否允许用户执行此请求并调用与请求对应的存储库方法。

于 2016-10-12T09:14:16.203 回答