簡體   English   中英

MVC存儲庫模式,如何進行安全修整?

[英]MVC repository pattern, how to security trim?

當前,我正在用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; }
    }

創建一個基類,將每個查詢轉換為檢查權限的查詢,並讓您的存儲庫類從中繼承。

像這樣:

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));
    }
}

您可能需要研究全局過濾器。 我將提供一個有關其工作原理的簡短示例:

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();
}

MVC存儲庫模式,如何進行安全修整?

存儲庫不應該進行訪問控制/安全調整。 僅提供查詢域對象的方法

在下面的代碼中

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

方法GetAddresses將返回所有可用地址。

方法GetAddressesInspectedBy將返回具體檢查員檢查的所有地址。

這兩種方法顯然是不同的,並且在存儲庫中彼此共存。 兩種方法都應該可用,但是調用哪種方法取決於存儲庫外部的業務邏輯/訪問控制。

但是現在我需要添加一些可以進一步過濾數據的東西。 根據登錄用戶的角色,應該對這些數據進行更多過濾。

返回給用戶的數據不應基於用戶的角色! 相反,它應該基於用戶的請求! 以及該請求是否可以執行取決於用戶的角色。

例如,可以允許管理員角色用戶請求以下每個請求

  1. 所有地址,
  2. 具體檢查員的地址,
  3. 由他自己檢查的地址。

三種請求類型中的每一種都將返回不同的結果,而與管理員角色無關!

雖然檢查員角色用戶只能被允許請求

  1. 僅由本人檢查的地址。

應用程序接收請求,檢查是否允許用戶執行此請求,並調用與該請求相對應的存儲庫方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM