ABP應用層——權限驗證


ABP應用層——權限驗證

ABP是“ASP.NET Boilerplate Project (ASP.NET樣板項目)”的簡稱。

ABP的官方網站http://www.aspnetboilerplate.com

ABP在Github上的開源項目https://github.com/aspnetboilerplate

 


幾乎所有的企業級應用程序都會有不同級別的權限驗證。權限驗證是用於檢查用戶是否允許某些指定操作。Abp有基礎設施讓你來實現權限驗證。

注意:關於IPermissionChecker接口

Abp權限系統使用IPermissionChecker去檢查授權。同時你可以根據需要實現你自己的方式,在module-zero項目中已經完整實現了。如果IPermissionChecker沒有被實現,NullPermissionChecker會被使用於授權所有權限給每個人。

定義權限

在使用驗證權限前,我們需要為每一個操作定義唯一的權限。Abp的設計是基於模塊化,所以不同的模塊可以有不同的權限。為了定義權限,一個模塊應該創建AuthorizationProvider的派生類。MyAuthorizationProvider繼承自AuthorizationProvider,換句話說就是AuthorizationProvider派生出MyAuthorizationProvider。例子如下:

復制代碼
public class MyAuthorizationProvider : AuthorizationProvider
{
    public override void SetPermissions(IPermissionDefinitionContext context)
    {
        var administration = context.CreatePermission("Administration");

        var userManagement = administration.CreateChildPermission("Administration.UserManagement");
        userManagement.CreateChildPermission("Administration.UserManagement.CreateUser");

        var roleManagement = administration.CreateChildPermission("Administration.RoleManagement");
    }
}
復制代碼

IPermissionDefinitionContext 有方法去獲取和創建權限。

一個權限有以下屬性:

  • Name:系統范圍內的唯一名字。把它定義為一個字符串常量是個不錯的注意。我們傾向於將“.”分割不同的層級,但並不要求這么做。你可以設置你任何喜歡的名字。唯一的規則就是這個名字必須是唯一的。
  • Display Name:使用一個本地化的字符串去顯示權限到UI。
  • Description:和Display Name類似。
  • IsGrantedByDefault:此權限是否授權給(已登陸)所有用戶,除非顯示指定。通常設置為False(默認值)。
  • MultiTenancySides:對租戶應用程序,一個權限可以基於租戶或者主機(原文:host)。這是個枚舉標識,因此權限可以應用於不同方面(原文:Both Sides)。
  • 一個權限可以有父權限和子權限。當然,這不會影響權限檢查,它只是在UI層對權限歸類有好處。創建authorizationprovider之后,我們應該在模塊的PreIntialize方法對它進行注冊。如下:
Configuration.Authorization.Providers.Add<MyAuthorizationProvider>()

authorizationprovider會自動注冊到依賴注入系統中。因此,authorization provider可以注入任何依賴(像是Repository)從而使用其他資源去創建權限定義。

檢查權限

(1)使用AbpAuthorize特性(Using AbpAuthorize attribute)

AbpAuthorize(AbpMvcAuthorize 對應 MVC Controllers and AbpApiAuthorize 對應 Web API Controllers)特性是最簡單和常用的方法去檢查權限。請考慮如下application service方法:

[AbpAuthorize("Administration.UserManagement.CreateUser")]
public void CreateUser(CreateUserInput input)
{
    //A user can not execute this method if he is not granted for "Administration.UserManagement.CreateUser" permission.
}

沒有獲得“Administration.UserManagement.CreateUser”權限的用戶不能夠調用CreateUser。

AbpAuthorize 特性也檢查當前用戶是否登錄 (使用 IAbpSession.UserId)。因此,如果我們將某個方法聲明為AbpAuthorize 特性,它至少會檢查用戶是否登錄。代碼如下: [AbpAuthorize]

public void SomeMethod(SomeMethodInput input)
{
    //A user can not execute this method if he did not login.
}

(2)AbpAuthorize屬性說明(AbpAuthorize attribute notes)

Abp使用動態方法攔截進行權限驗證。因此,使用AbpAuthorize特性的方法會有些限制。如下:

  • 不能應用於私有(private)方法
  • 不能應用於靜態(static)方法
  • 不能應用於非注入(non-injected)類(我們必須用依賴注入)。

此外,

  • AbpAuthorize特性可以應用於任何的Public方法,如果此方法被接口調用(比如在Application Services中通過接口調用)
  • 方法是虛(virtual)方法,如果此方法直接被類引用進行調用(像是ASP.NET MVC 或 Web API 的控制器)。
  • 方式是虛(virtual)方法,如果此方法是protected。

注意:有三種AbpAuthorize 特性:

  • 在應用程序服務中(application layer),我們使用Abp.Authorization.AbpAuthorize;
  • 在MVC控制器(web layer)中,我們使用Abp.Web.Mvc.Authorization.AbpMvcAuthorize;
  • 在ASP.NET Web API,我們使用 Abp.WebApi.Authorization.AbpApiAuthorize。

這三個類繼承自不同的地方。

  • 在MVC中,它繼承自MVC自己的Authorize類。
  • 在Web API,它繼承自Web API 的Authorize類。因此,它最好是繼承到MVC和Web API中。
  • 但是,在Application 層,它完全是由Abp自己實現沒有擴展子任何類。

(3)使用IPermissionChecker

AbpAuthorize 適用於大部分的情況,但是某些情況下,我們還是需要自己在方法體里進行權限驗證。我們可以注入和使用IPermissionChecker對象。如下邊的代碼所示:

復制代碼
public void CreateUser(CreateOrUpdateUserInput input)
{
    if (!PermissionChecker.IsGranted("Administration.UserManagement.CreateUser"))
    {
        throw new AbpAuthorizationException("You are not authorized to create user!");
    }

    //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.
}
復制代碼

當然,你可以寫入任何邏輯,由於IsGranted方法只是簡單返回true或false(它還有異步版本哦)。如你簡單的檢查一個權限並拋出一個異常如上邊代碼那樣,你可以用Authorize方法:

public void CreateUser(CreateOrUpdateUserInput input)
{
    PermissionChecker.Authorize("Administration.UserManagement.CreateUser");

    //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.
}

由於權限驗證通常實現與Application層,ApplicationService基礎類注入和定義了PermissionChecker屬性。因此,權限檢查器允許你在Application Service類使用,而不需要顯示注入。


 

希望更多國內的架構師能關注到ABP這個項目,也許這其中有能幫助到您的地方,也許有您的參與,這個項目可以發展得更好。

歡迎加ABP架構設計交流QQ群:134710707

ABP架構設計交流群

 

點這里進入ABP系列文章總目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM