Casbin——專注、高效的訪問控制框架

zerokirin發表於2020-09-22

什麼是casbin

幾乎所有的系統在設計的時候都要有許可權管理的模組,如果每次開發都要重新實現一次許可權管理,光是想想就覺得無聊,程式設計師嘛能用輪子就用輪子,因此casbin出現了。

casbin是一個強大、高效的訪問控制庫。支援常用的多種訪問控制模型,如ACL/RBAC/ABAC等。可以實現靈活的訪問許可權控制。同時,casbin支援多種程式語言,Go/Java/Node/PHP/Python/.NET/Rust

casbin的特點

  1. 支援自定義請求的格式,預設的請求格式為{subject, object, action}
  2. 具有訪問控制模型model和策略policy兩個核心概念。
  3. 支援RBAC中的多層角色繼承,不止主體可以有角色,資源也可以具有角色。
  4. 支援超級使用者,如 rootAdministrator,超級使用者可以不受授權策略的約束訪問任意資源。
  5. 支援多種內建的操作符,如 keyMatch,方便對路徑式的資源進行管理,如 /foo/bar 可以對映到 /foo*

不是casbin該管的事

  1. 身份認證 authentication(即驗證使用者的使用者名稱、密碼),casbin只負責訪問控制。應該有其他專門的元件負責身份認證,然後由casbin進行訪問控制,二者是相互配合的關係。
  2. 管理使用者列表或角色列表。 Casbin 認為由專案自身來管理使用者、角色列表更為合適, 使用者通常有他們的密碼,但是 Casbin 的設計思想並不是把它作為一個儲存密碼的容器。 而是儲存RBAC方案中使用者和角色之間的對映關係。

常用授權模型

ACL

ACLAccess Control List的縮寫,稱為訪問控制列表. 定義了誰可以對某個資料進行何種操作. 關鍵資料模型有: 使用者, 許可權.

ACL規則簡單, 也帶來一些問題: 資源的許可權需要在使用者間切換的成本極大; 使用者數或資源的數量增長, 都會加劇規則維護成本;

典型應用

  1. 檔案系統

檔案系統的檔案或資料夾定義某個賬號(user)或某個群組(group)對檔案(夾)的讀(read)/寫(write)/執行(execute)許可權.

  1. 網路訪問

防火牆: 伺服器限制不允許指定機器訪問其指定埠, 或允許特定指定伺服器訪問其指定幾個埠.

RBAC

RBACRole-based access control的縮寫, 稱為 基於角色的訪問控制. 核心資料模型有: 使用者, 角色, 許可權.

使用者具有角色, 而角色具有許可權, 從而表達使用者具有許可權.

由於有角色作為中間紐帶, 當新增使用者時, 只需要為使用者賦予角色, 使用者即獲得角色所包含的所有許可權.

RBAC存在多個擴充套件版本, RBAC0RBAC1RBAC2RBAC3。這些版本的詳細說明可以引數這裡。我們在實際專案中經常使用的是RBAC1,即帶有角色繼承概念的RBAC模型。

ABAC

ABACAttribute-based access control的縮寫, 稱為基於屬性的訪問控制.

許可權和資源當時的狀態(屬性)有關, 屬性的值可以用於正向判斷(符合某種條件則通過), 也可以用於反向判斷(符合某種條件則拒絕):

典型應用

  1. 論壇的評論許可權, 當帖子是鎖定狀態時, 則不再允許繼續評論;
  2. Github 私有倉庫不允許其他人訪問;
  3. 發帖者可以編輯/刪除評論(如果是RBAC, 會為發帖者定義一個角色, 但是每個帖子都要新增一條使用者/發帖角色的記錄);
  4. 微信聊天訊息超過2分鐘則不再允許撤回;
  5. 12306 只有實名認證後的賬號才能購票;
  6. 已過期的付費賬號將不再允許使用付費功能;

實現一個簡單的ACL授權驗證模型

安裝

go get github.com/casbin/casbin

編寫模型檔案(Model.conf)

具體語法可以參考官方教程 Model語法

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

[policy_effect]
e = some(where (p.eft == allow))

編寫策略檔案(Policy.csv)

p, dajun, data1, read
p, lizi, data2, write

上述檔案的具體意義如下

有一條p(策略),定義了dajun(sub), data1(obj), read(act),語義化就是dajun可以對data1執行read方法

code

package main

import (
  "fmt"
  "log"

  "github.com/casbin/casbin/v2"
)

func check(e *casbin.Enforcer, sub, obj, act string) {
  ok, _ := e.Enforce(sub, obj, act)
  if ok {
    fmt.Printf("%s CAN %s %s\n", sub, act, obj)
  } else {
    fmt.Printf("%s CANNOT %s %s\n", sub, act, obj)
  }
}

func main() {
  e, err := casbin.NewEnforcer("./model.conf", "./policy.csv")
  if err != nil {
    log.Fatalf("NewEnforecer failed:%v\n", err)
  }

  check(e, "dajun", "data1", "read")
  check(e, "lizi", "data2", "write")
  check(e, "dajun", "data1", "write")
  check(e, "dajun", "data2", "read")
}

至此一個簡單的ACL模型的demo就完成了

社群

官方網站:casbin.org

github地址:go-casbin

官方論壇:forum.casbin.com

QQ 群:546057381( Casbin 訪問控制討論群)

社群為多個語言的多個框架適配了相應的中介軟體,未來將會有更多框架支援,如果你希望參與貢獻,歡迎加入casbin社群

參考

cloud.tencent.com/developer/articl...

juejin.im/post/6844904191257739277

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章