簡體   English   中英

限制DbContext訪問的體系結構

[英]Architecture for Restricting DbContext Access

我目前正在編寫一個rest框架,我想創建一種方法來不僅限制通過讀取而且還可以通過寫入來限制對某些實體的訪問。 當前,我已經創建了一個基本的DbContext,它可以像這樣處理授權(我省略了一些代碼(例如,選項分配),因為它們與問題無關):

public abstract class AuthorizedDbContext : DbContext
{
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var constraintOptions = this._authorizationOptions.ConstraintOptions;
        constraintOptions.ApplyStaticConstraint(modelBuilder, this);
        base.OnModelCreating(modelBuilder);
    }

    public async override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
    {
        this.VerifyResourceAccess();
        return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
    }

    protected void VerifyResourceAccess()
    {
        if (false == ChangeTracker.HasChanges())
        {
            return;
        }

        //WARNING: if you don't set the change tracking behavior to no tracking, you could reload entities by accident
        var previousTrackingBehavior = this.ChangeTracker.QueryTrackingBehavior;
        this.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

        this._authorizationOptions.ContextValidator.ValidateAndThrow(this);

        this.ChangeTracker.QueryTrackingBehavior = previousTrackingBehavior;
    }
} 

目前,我注入了一個dbcontext驗證程序,該驗證程序用於處理限制更新和保存更改時的其他驗證。

用戶放心,知道使用此授權上下文時,如果不通過用戶在其代碼中定義的所有驗證,就無法更新實體。

但是,這種體系結構很爛,並且嚴重限制了用戶代碼的靈活性,例如,如果用戶要使用IdentityDbContext,除非我創建從IdentityDbContext<AppUser>繼承的AuthorizedDbContext,否則將無法實現。

相反,我更喜歡在它們的上下文周圍使用包裝器。 例如

//Pseudo-Code
AuthorizedDbContextScope<T>: IDisposable
    where T: DbContext
{
    public void ApplyConstraints()
    {
        this._options.DynamicConstraints.Foreach(EntityFrameWorkZ.ApplyDynamicFilterFromAction)
    }
}

此包裝的唯一問題是1.我無法公開DbContext功能,無法覆蓋范圍內的保存更改,我必須強制用戶在包裝上調用保存更改。

我可以在啟動時使用DynamicProxy從其DbContext繼承,但是這似乎有些矯,過正,這會嚴重減慢項目的啟動速度。

如果有人對我可以如何更好地普遍限制我的更新提出建議,請告訴我。

如何在不限制用戶代碼繼承靈活性的情況下完全限制數據庫更改?

這是主觀的,但我會試一試。

  1. 如果要專門定義要授權的實體,可以使用Authorize屬性。 自從我使用它已經有一段時間了,但是我記得自定義行為的能力。 如果這不起作用,則可以編寫自己的裝飾並修飾您關心的實體-使用該屬性直接處理授權,或者簡單地將其用作標識符並在提交更改之前對對象進行反映。 這將為您提供一些按應用程序域自定義的靈活性。
  2. 如果這對您不起作用,那么您實際上嘗試自定義幾種類型的上下文? 如果是兩個,那么不存在的第三個似乎還很遙遠……那么,yagni。 如果這樣做,可以將授權邏輯集中在一個地方,並創建兩個基類來使用它。 值得一提的是,IdentityDbContext繼承自DbContext,因此您可以在授權終止的地方進行概括。 或者,如果需要它們表現不同,則可以使用接口。
  3. 使用IdentityDbContext交換對DbContext的所有引用,然后通過自定義從中繼承。 同樣,DbContext是IdentityDbContext的根。 我不記得使用一個與另一個相比會產生大量開銷,但是可能取決於您的域。

所有這些想法都可能受解決方案的體系結構以及一個或多個應用程序使用該功能的限制。

暫無
暫無

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

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