他人のコードからgolangシリーズを学ぶ--03

6783 ワード

このブログはhttps://github.com/LyricTian/gin-adminこのプロジェクトで学んだgolangに関する知識.
著者はプロジェクトでgithub.com/casbin/casbinを使用して権限制御を行ったが,このライブラリ自体はこれまで使ったことがなく,ちょうどこのプロジェクトを通じて使用を学ぶことができる.もちろんこのブログではcasbinの使用について詳しく説明しませんが、興味のある方は公式サイトで具体的な使用ドキュメントを見ることができます.

casbinについて


一般的なアクセス制御モデル


ABAC:属性ベースのアクセス制御.
DAC:自主アクセス制御モデル(DAC,Discretionary Access Control)は、自主アクセス制御ポリシーに基づいて構築されたモデルであり、合法的なユーザーがユーザーまたはユーザーグループとしてポリシーに規定されたゲストにアクセスできるようにするとともに、非許可のユーザーがゲストにアクセスすることを阻止する.ゲスト権限を持つユーザーは、そのゲストの権限を他のユーザーに割り当てることができます.
ACL:ACLは最も早く、最も基本的なアクセス制御メカニズムであり、その原理は非常に簡単です.各リソースには、どのユーザーがこのリソースに対してCRUDの操作を実行できるかを記録するリストがあります.システムがこのリソースにアクセスしようとすると、まずこのリストに現在のユーザーに関するアクセス権限があるかどうかを確認し、現在のユーザーが対応する操作を実行できるかどうかを決定します.要するに、ACLはリソース向けのアクセス制御モデルであり、そのメカニズムは「リソース」をめぐって展開される.
RBAC:ロールのアクセス制御(RBAC,Role Based Access Control)に基づいて、ユーザーと権限の間に「ロール(Role)」の概念を導入し、ロールはユーザーと権限の関係をデカップリングします.

casbin


casbinは、プロファイルを使用してアクセス制御モデルを設定します.Casbinでは、アクセス制御モデルはPERM(Policy,Effect,Request,Matcher)に基づくファイルとして抽象化される.
Casbinの中で最も基本的で最も簡単なモデルはACLです.ACLのモデルCONFは次のとおりです.
# Request definition
[request_definition]
r = sub, obj, act

# Policy definition
[policy_definition]
p = sub, obj, act

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

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

Request definition:要求を表し、上記の構成ではr = sub, obj, actは1つの要求に3つの標準要素がある:要求主体、要求オブジェクト、要求操作.
Policy definition:ポリシーを表し、具体的な権限定義のルールが何であるかを示します.上記の構成ではp = sub, obj, actです.
Policy effect:Effectは、1つのリクエストがルールを満たしている場合、リクエストに同意する必要があるかどうかを判断するために使用されます.
Matchers:要求があり、ルールがある場合、要求がルールに一致するかどうかはmatcherが判断する

ACL with superuser栗


モデルの構成:
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

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

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

Policey構成:
p, alice, data1, read
p, bob, data2, write

私たちが要求する時:alice,data 1,readはマッチングルールに基づいて、マッチングの結果はtrueです.私たちが要求する時:alice,data 1,writeはマッチングルールに基づいて、マッチングのルールはfalseです.

RESful(KeyMatch 2)栗


モデルの構成:
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

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

[matchers]
m = r.sub == p.sub && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)

Policy定義:
p, alice, /alice_data/:resource, GET
p, alice, /alice_data2/:id/using/:resId, GET
alice, /alice_data/hello, GETがmatchersルールに従ってp, alice, /alice_data/:resource, GETに一致することを要求するとtrueに戻り、alice, /alice_data/hello, POSTがmatchersルールに従って一致しないことを要求するとfalseに戻る

RBAC栗


モデルの構成:
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

ここでは、role_definitionロール定義が導入され、gは、どのユーザがどのロールに属しているかを判断するために使用される
Policy構成:
p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write

g, alice, data2_admin
alice, data2, readにmatchersに従ってaliceがdata 2であることを要求するとadminキャラクタ、r.obj == p.obj && r.act == p.actなのでtrueに戻ります

gin-adminプロジェクトでの使用


ここではまず著者コードのcasbinの使用を整理します.前にcasbinの他のいくつかのプロジェクトでの使用を見たので、少し乱れています.gin-adminというプロジェクトの時も最初は少しぼんやりしていて、使い方が理解できませんでしたが、コードを整理してから、gin-adminの著者の使用はとてもいいと思います.
gin-adminプロジェクトにおけるcasbinの使用について
  • 定義CasbinAdapter
  • 初期化casbin
  • 非同期ロードcasbin権限
  • CasbinAdapterが定義されています


    著者はgin-admin/internal/module/adapter/casbin.goではCasbinAdapterが定義されています.
    // CasbinAdapter casbin 
    type CasbinAdapter struct {
    	RoleModel         model.IRole
    	RoleMenuModel     model.IRoleMenu
    	MenuResourceModel model.IMenuActionResource
    	UserModel         model.IUser
    	UserRoleModel     model.IUserRole
    }
    

    ここで、CasbinAdapterは、casbinAdapterインターフェース、すなわちCasbinAdapterがLoadPolicy,SavePolicy,AddPolicy,RemovePolicyメソッドを実装し、著者らは、LoadPolicyによってユーザ権限およびロール権限をデータベースからロードする.

    初期化


    権限の初期化は、次のコードによって行われます.
    func InitCasbin(adapter persist.Adapter) (*casbin.SyncedEnforcer, func(), error) {
    	cfg := config.C.Casbin
    	if cfg.Model == "" {
    		return new(casbin.SyncedEnforcer), nil, nil
    	}
    
    	e, err := casbin.NewSyncedEnforcer(cfg.Model)
    	if err != nil {
    		return nil, nil, err
    	}
    	e.EnableLog(cfg.Debug)
    	err = e.InitWithModelAndAdapter(e.GetModel(), adapter)
    	if err != nil {
    		return nil, nil, err
    	}
    	e.EnableEnforce(cfg.Enable)
    
    	cleanFunc := func() {}
    	if cfg.AutoLoad {
    		e.StartAutoLoadPolicy(time.Duration(cfg.AutoLoadInternal) * time.Second)
    		cleanFunc = func() {
    			e.StopAutoLoadPolicy()
    		}
    	}
    
    	return e, cleanFunc, nil
    }
    

    非同期casbin権限のロード


    このセクションでは、主にページを介して権限の構成を行った後、gin-admin/internal/app/bll/impl/bll/b_で権限を再ロードする必要があります.casbin.go中:
    var chCasbinPolicy chan *chCasbinPolicyItem
    
    type chCasbinPolicyItem struct {
    	ctx context.Context
    	e   *casbin.SyncedEnforcer
    }
    
    func init() {
    	chCasbinPolicy = make(chan *chCasbinPolicyItem, 1)
    	go func() {
    		for item := range chCasbinPolicy {
    			err := item.e.LoadPolicy()
    			if err != nil {
    				logger.Errorf(item.ctx, "The load casbin policy error: %s", err.Error())
    			}
    		}
    	}()
    }
    
    // LoadCasbinPolicy  casbin 
    func LoadCasbinPolicy(ctx context.Context, e *casbin.SyncedEnforcer) {
    	if !config.C.Casbin.Enable {
    		return
    	}
    
    	if len(chCasbinPolicy) > 0 {
    		logger.Infof(ctx, "The load casbin policy is already in the wait queue")
    		return
    	}
    
    	chCasbinPolicy 

    アクセス権を変更するインタフェースでは、LoadCasbinPolicyを呼び出すことでアクセス権ポリシーがロードされます.

    まとめ


    このプロジェクトについて3つの文章を整理して、多くのことを学んで、実はこの文章に着いて、作者の全体のコードは自分ですでにはっきりしていて、多くの人は作者のプロジェクトの目録が複雑すぎると感じて、いくつかの重複コードがあって、あなたがコードのパトロールを整理し始めたばかりの时また愚かな顔を感じて、しかしあなたが辛抱強く整理した后に、あなたは発見することができて、このように書くのはもとはこのようにあるいはそのような利益があります.作者の残りのコードはwebインタフェースの論理についてで、整理していません.
    次の計画は今回のコードの勉強を通じて、blogのwebプロジェクトを書くことです.また、次のオープンソースプロジェクトコードを探して学習します.

    拡張読書

  • https://casbin.org/zh-CN/editor
  • https://casbin.org/docs/zh-CN/overview
  • https://www.cnblogs.com/yjf512/p/12200206.html