2017-07-30 99 views
3

好的,基於自定義策略的ASP.NET核心授權。我有點理解這個新的身份框架的想法,但仍然不能100%清楚你可以用這個來實現什麼。假設我們在HomeController中有一個名爲List的Action。此操作將查詢並顯示數據庫中的產品列表。必須訪問此列表的用戶必須是Marketing部門的一部分。因此,在我們的政策中,我們會檢查用戶是否擁有稱爲「分區」的聲明,並且其價值是「營銷」如果是,那麼他將被允許看到清單,否則不會。我們可以這樣裝飾我們的動作:基於ASP.NET核心自定義策略的授權 - 不清楚

[Authorize(Policy = "ProductsAccess")] 
public IActionResult List() 
{ 
    //do query and return the products view model 
    return View(); 
} 

所有這一切都很好。它會完美地工作。

場景1:如果我想在產品級別添加策略,並且根據策略,用戶將只能看到他的部門的產品,該怎麼辦?所以營銷人員會看到他的產品,R & D會看到他的等等。我怎樣才能做到這一點?這可以通過政策來完成嗎?如果是的話如何?

情景2:在現場級訪問情況如何?比方說,也許我想隱藏某些領域?例如:所有產品都將具有必須可供管理員查看的某些列,並隱藏給其他用戶?這可以使用自定義策略完成嗎?如果是的話如何?

回答

4

對於場景1您可以使用resource based authorization

在本質上,你會注入到IAuthorizationService您的服務或控制器,然後和有一個或多個授權處理其派生形式AuthorizationHandler<TRequirement, TDocument>,然後調用

if(await _authorizationService.AuthorizeAsync(User, document, "MyPolicy")) 
{ 
    // Success, user has access to it 
} 

下行:你必須獲取所有產品從數據庫中,然後在內存中過濾,所以它適用於單個文檔或更小的數據,在那裏你不需要分頁。即使數據量較小(即,如果您請求50種產品,但用戶無法訪問其中的40種產品,即使頁面大小爲50,也只會返回10種產品),但分頁會打破它。

使用EF Core 2.0(這是如果您使用EF Core作爲您的ORM)的替代方案。您可以添加全局篩選器,這將應用於某個實體的所有查詢。

欲瞭解更多信息,請參閱Entity Framework Core 2.0 Announcement博客文章:

public class BloggingContext : DbContext 
{ 
    public DbSet<Blog> Blogs { get; set; } 
    public DbSet<Post> Posts { get; set; } 

    public int TenantId {get; set; } 

    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Post>() 
      .HasQueryFilter(p => !p.IsDeleted && 
        p.TenantId == this.TenantId); 
    } 
} 

它可能會或可能不適合你的情況,這取決於如果你有一個行級數據,可以使用(即某種「資源所有者「字段)。

方案2對於Identity來說是不可能的,據我所知,你必須自己實現一些東西,但這是一個非常複雜的話題(如果你曾經使用過Dynamics CRM,你知道我的意思)。

更新

只是一個快速的實現,你可以嘗試換一個ExpandoObject在你的反應(這是什麼時,你使用dynamic關鍵字基本)和疊代,刪除用戶沒有按性能」在從控制器操作中返回它之前可以訪問它,或者寫入一個授權過濾器,該過濾器將自動爲特定或所有控制器執行此操作。

對於一個粗略的想法(關於如何構建/使用expando對象),請參閱我的回答here

2

我不認爲政策的目的是解決你的情況。我不確定它是否可能,即使它會,我覺得代碼本身會受到它帶來的複雜性和困惑的困擾。我不會授予我的授權過濾器那麼多的責任。

至於你的第二種情況,你可以跳過基於角色,聲明或當前用戶的任何內容在視圖中輸出某些數據。似乎不必要的複雜來解決這個問題。

使用策略來完成它的功能,授權用戶是否允許運行一個方法。與返回的內容有什麼不同?在正常的代碼流中處理它。