跳转至主要内容

API Overview

此概述仅向您展示如何使用 Casbin API,并不解释如何安装 Casbin 或其工作原理。 您可以在这里找到这些教程:Casbin 的安装Casbin 的工作原理。 所以,当您开始阅读这个教程时,我们假设您已经完全安装并导入了 Casbin 到您的代码中。

Enforce API

让我们从 Casbin 的 Enforce API 开始。 我们将从 model.conf 加载一个 RBAC 模型,并从 policy.csv 加载策略。 您可以在这里了解模型语法,我们在这个教程中不会讨论它。 我们假设您能理解下面给出的配置文件:

model.conf

[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

policy.csv

p, admin, data1, read
p, admin, data1, write
p, admin, data2, read
p, admin, data2, write
p, alice, data1, read
p, bob, data2, write
g, amber, admin
g, abc, admin

阅读配置文件后,请阅读以下代码。

// Load information from files.
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
log.Fatalf("Error, detail: %s", err)
}
ok, err := enforcer.Enforce("alice", "data1", "read")

此代码从本地文件加载访问控制模型和策略。 casbin.NewEnforcer() 函数将返回一个执行器。 它会将其两个参数识别为文件路径,并从那里加载文件。 过程中发生的错误存储在变量 err 中。 此代码使用默认适配器加载模型和策略,当然,您也可以使用第三方适配器达到相同的效果。

ok, err := enforcer.Enforce("alice", "data1", "read") 代码用于确认访问权限。 如果 Alice 可以使用读操作访问 data1,ok 的返回值将为 true;否则,将为 false。 在此示例中,ok 的值为 true

EnforceEx API

有时您可能想知道是哪个策略允许了请求,所以我们准备了 EnforceEx() 函数。 您可以这样使用它:

ok, reason, err := enforcer.EnforceEx("amber", "data1", "read")
fmt.Println(ok, reason) // true [admin data1 read]

EnforceEx() 函数将在返回值 reason 中返回确切的策略字符串。 在此示例中,amber 是一个 admin 角色,所以策略 p, admin, data1, read 允许此请求为 true。 此代码的输出在注释中。

Casbin 提供了许多类似于此的 API。 这些 API 在基本功能上增加了一些额外的功能。 它们包括:

  • ok, err := enforcer.EnforceWithMatcher(matcher, request)

    此函数使用一个匹配器。

  • ok, reason, err := enforcer.EnforceExWithMatcher(matcher, request)

    这是EnforceWithMatcher()EnforceEx()的组合。

  • boolArray, err := enforcer.BatchEnforce(requests)

    此函数允许一系列的任务,并返回一个数组。

这是Casbin的一个简单用例。 你可以使用Casbin使用这些API启动一个授权服务器。 我们将在接下来的段落中向你展示一些其他类型的API。

管理API

获取API

这些API用于在策略中检索特定对象。 在这个例子中,我们正在加载一个执行器并从中检索一些东西。

请看下面的代码:

enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
allSubjects := enforcer.GetAllSubjects()
fmt.Println(allSubjects)

与前面的例子类似,前四行用于从本地文件加载必要的信息。 我们不会在这里进一步讨论。

代码allSubjects := enforcer.GetAllSubjects()检索策略文件中的所有主题,并将它们作为数组返回。 然后我们打印那个数组。

通常,代码的输出应该是:

[admin alice bob]

你也可以将函数GetAllSubjects()更改为GetAllNamedSubjects(),以获取当前命名策略中出现的主题列表。

同样,我们为Objects, Actions, Roles准备了GetAll函数。 要访问这些函数,你只需要在函数名中将Subject替换为所需的类别。

此外,还有更多的策略获取器可用。 调用方法和返回值与上述类似。

  • policy = e.GetPolicy()检索策略中的所有授权规则。
  • filteredPolicy := e.GetFilteredPolicy(0, "alice")检索策略中具有指定字段过滤器的所有授权规则。
  • namedPolicy := e.GetNamedPolicy("p")检索命名策略中的所有授权规则。
  • filteredNamedPolicy = e.GetFilteredNamedPolicy("p", 0, "bob")检索具有指定字段过滤器的命名策略中的所有授权规则。
  • groupingPolicy := e.GetGroupingPolicy()检索策略中的所有角色继承规则。
  • filteredGroupingPolicy := e.GetFilteredGroupingPolicy(0, "alice")检索具有指定字段过滤器的策略中的所有角色继承规则。
  • namedGroupingPolicy := e.GetNamedGroupingPolicy("g")检索策略中的所有角色继承规则。
  • namedGroupingPolicy := e.GetFilteredNamedGroupingPolicy("g", 0, "alice")检索具有指定字段过滤器的策略中的所有角色继承规则。

添加,删除,更新 API

Casbin提供了各种API,用于在运行时动态添加,删除或修改策略。

以下代码演示了如何添加,删除和更新策略,以及如何检查策略是否存在:

// load information from files
enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}

// add a policy and use HasPolicy() to confirm
enforcer.AddPolicy("added_user", "data1", "read")
hasPolicy := enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // true, the policy was added successfully

// remove a policy and use HasPolicy() to confirm
enforcer.RemovePolicy("alice", "data1", "read")
hasPolicy = enforcer.HasPolicy("alice", "data1", "read")
fmt.Println(hasPolicy) // false, the policy was removed successfully

// update a policy and use HasPolicy() to confirm
enforcer.UpdatePolicy([]string{"added_user", "data1", "read"}, []string{"added_user", "data1", "write"})
hasPolicy = enforcer.HasPolicy("added_user", "data1", "read")
fmt.Println(hasPolicy) // false, the original policy has expired
hasPolicy = enforcer.HasPolicy("added_user", "data1", "write")
fmt.Println(hasPolicy) // true, the new policy is in effect

通过使用这些API,您可以动态编辑您的策略。 同样,我们也为FilteredPolicy, NamedPolicy, FilteredNamedPolicy, GroupingPolicy, NamedGroupingPolicy, FilteredGroupingPolicy, FilteredNamedGroupingPolicy提供了类似的API。 要使用它们,只需将函数名称中的Policy替换为适当的类别。

此外,通过将参数更改为数组,您可以批量编辑您的策略。

例如,考虑像这样的函数:

enforcer.UpdatePolicy([]string{"eve", "data3", "read"}, []string{"eve", "data3", "write"})

如果我们将Policy更改为Policies并按如下方式修改参数:

enforcer.UpdatePolicies([][]string{{"eve", "data3", "read"}, {"jack", "data3", "read"}}, [][]string{{"eve", "data3", "write"}, {"jack", "data3", "write"}})

那么我们可以批量编辑这些策略。

同样的操作也可以应用于GroupingPolicy, NamedGroupingPolicy

AddEx API

Casbin提供了AddEx系列API,以帮助用户批量添加规则。

AddPoliciesEx(rules [][]string) (bool, error)
AddNamedPoliciesEx(ptype string, rules [][]string) (bool, error)
AddGroupingPoliciesEx(rules [][]string) (bool, error)
AddNamedGroupingPoliciesEx(ptype string, rules [][]string) (bool, error)
SelfAddPoliciesEx(sec string, ptype string, rules [][]string) (bool, error)

这些方法与没有Ex后缀的方法的区别在于,如果其中一个规则已经存在,它们将继续检查下一个规则,而不是立即返回false。

例如,让我们比较AddPoliciesAddPoliciesEx

您可以通过将以下代码复制到casbin下的测试中来运行并观察。

func TestDemo(t *testing.T) {
e, err := NewEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}
e.ClearPolicy()
e.AddPolicy("user1", "data1", "read")
fmt.Println(e.GetPolicy())
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})

// policy {"user1", "data1", "read"} now exists

// Use AddPolicies to add rules in batches
ok, _ := e.AddPolicies([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} failed to add because {"user1", "data1", "read"} already exists
// AddPolicies returns false and no other policies are checked, even though they may not exist in the existing ruleset
// ok == false
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}})

// Use AddPoliciesEx to add rules in batches
ok, _ = e.AddPoliciesEx([][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
fmt.Println(e.GetPolicy())
// {"user2", "data2", "read"} is added successfully
// because AddPoliciesEx automatically filters the existing {"user1", "data1", "read"}
// ok == true
fmt.Println(ok)
testGetPolicy(t, e, [][]string{{"user1", "data1", "read"}, {"user2", "data2", "read"}})
}

RBAC API

Casbin为您提供了一些API,以便修改RBAC模型和策略。 如果您熟悉RBAC,您可以轻松使用这些API。

在这里,我们只向您展示如何使用Casbin的RBAC API,而不讨论RBAC本身。 您可以在这里获取更多详细信息。

我们使用以下代码来加载模型和策略,就像以前一样。

enforcer, err := casbin.NewEnforcer("./example/model.conf", "./example/policy.csv")
if err != nil {
fmt.Printf("Error, details: %s\n", err)
}

然后,我们可以使用Enforcer enforcer的实例来访问这些API。

roles, err := enforcer.GetRolesForUser("amber")
fmt.Println(roles) // [admin]
users, err := enforcer.GetUsersForRole("admin")
fmt.Println(users) // [amber abc]

GetRolesForUser()返回一个包含amber所有角色的数组。 在这个例子中,amber只有一个角色,那就是admin,所以数组roles[admin]。 同样,您可以使用GetUsersForRole()来获取属于某个角色的用户。 此函数的返回值也是一个数组。

enforcer.HasRoleForUser("amber", "admin") // true

您可以使用 HasRoleForUser() 来确认用户是否属于该角色。 在这个例子中,amber是admin的成员,所以函数的返回值是 true

fmt.Println(enforcer.Enforce("bob", "data2", "write")) // true
enforcer.DeletePermission("data2", "write")
fmt.Println(enforcer.Enforce("bob", "data2", "write")) // false

您可以使用 DeletePermission() 来删除一个权限。

fmt.Println(enforcer.Enforce("alice", "data1", "read")) // true
enforcer.DeletePermissionForUser("alice", "data1", "read")
fmt.Println(enforcer.Enforce("alice", "data1", "read")) // false

并使用 DeletePermissionForUser() 来为用户删除一个权限。

Casbin有许多像这样的API。 他们的调用方法和返回值与上述API的风格相同。 您可以在下一个文档中找到这些API。