メインコンテンツにスキップ

ABAC

ABACモデルとは何ですか?

ABACはAttribute-Based Access Controlの略です。 これにより、文字列の値自体を使用するのではなく、主体、オブジェクト、またはアクションの属性(プロパティ)を使用してアクセスを制御できます。 XACMLという複雑なABACアクセス制御言語を聞いたことがあるかもしれません。 一方、CasbinのABACははるかにシンプルです。 CasbinのABACでは、モデル要素の文字列の代わりに構造体やクラスのインスタンスを使用できます。

公式のABAC例を見てみましょう:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

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

[matchers]
m = r.sub == r.obj.Owner

マッチャーでは、r.objの代わりにr.obj.Ownerを使用します。 Enforce()関数に渡されるr.objは文字列ではなく、構造体またはクラスのインスタンスになります。 Casbinはリフレクションを使用して、その構造体またはクラスのobjメンバ変数を取得します。

ここにr.objの構造体またはクラスの定義があります:

type testResource struct {
Name string
Owner string
}

JSONを通じてエンフォーサーにパラメータを渡したい場合は、e.EnableAcceptJsonRequest(true)で機能を有効にする必要があります。

例えば:

e, _ := NewEnforcer("examples/abac_model.conf")
e.EnableAcceptJsonRequest(true)

data1Json := `{ "Name": "data1", "Owner": "bob"}`

ok, _ := e.Enforce("alice", data1Json, "read")
メモ

JSONパラメータの受け入れ機能を有効にすると、パフォーマンスが1.1から1.5倍低下する可能性があります。

ABACの使い方は?

ABACを使用するには、次の2つのことを行う必要があります:

  1. モデルマッチャーで属性を指定します。
  2. 要素の引数として構造体またはクラスのインスタンスをCasbinのEnforce()関数に渡します。
危険

現在、r.subr.objr.actなどのリクエスト要素のみがABACをサポートしています。 Casbinのポリシーで構造体やクラスを定義する方法がないため、p.subのようなポリシー要素では使用できません。

tip

マッチャーで複数のABAC属性を使用できます。 例:m = r.sub.Domain == r.obj.Domain

tip

CSVのセパレータと競合するポリシーでカンマを使用する必要がある場合は、ステートメントを引用符で囲むことでエスケープできます。 例えば、"keyMatch("bob", r.sub.Role)"は分割されません。

複雑で大量のABACルールのモデルをスケーリングする

上記のABACモデルの実装は、その核心でシンプルです。 しかし、多くの場合、認証システムは複雑で大量のABACルールを必要とします。 この要件を満たすために、モデルではなくポリシーにルールを追加することを推奨します。 これは、eval()機能構造を導入することで実現できます。 ここに例があります:

これは、ABACモデルを定義するために使用されるCONFファイルの定義です。

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub_rule, obj, act

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

[matchers]
m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act

この例では、p.sub_ruleはポリシーで使用される必要な属性を含む構造体またはクラス(ユーザー定義型)です。

これは、Enforcementのためのモデルに対して使用されるポリシーです。 これで、eval()にパラメータとして渡されたオブジェクトインスタンスを使用して、特定のABAC制約を定義することができます。

p, r.sub.Age > 18, /data1, read
p, r.sub.Age < 60, /data2, write