角色鉴权
Casbin 是一 个强大的、高效的开源访问控制框架,其权限管理机制支持多种访问控制模型。
官网文档:https://casbin.org/
Casbin 是什么
Casbin 可以:
- 支持自定义请求的格式,默认的请求格式为
{subject, object, action}
。 - 具有访问控制模型model和策略policy两个核心概念。
- 支持RBAC中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
- 支持内置的超级用户 例如:
root
或administrator
。超级用户可以执行任何操作而无需显式的权限声明。 - 支持多种内置的操作符,如
keyMatch
,方便对路径式的资源进行管理,如/foo/bar
可以映射到/foo*
Casbin 不能:
- 身份认证 authentication(即验证用户的用户名和密码),Casbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 Casbin 进行访问控制,二者是相互配合的关系。
- 管理用户列表或角色列表。 Casbin 认为由项目自身来管理用户、角色列表更为合适, 用户通常有他们的密码,但是 Casbin 的设计思想并不是把它作为一个存储密码的容器。 而是存储RBAC方案中用户和角色之间的映射关系。
提示
注意:
- 1、在 Midway v3.6.0 之后可用
- 2、Midway 只是封装了 Casbin 的 API 并提供简单的支持,策略规则编写请查看 官方文档
- 3、Casbin 不提供登录,只提供现有用户的鉴权,需要搭配 passport 等获取用户信息的组件来使用
相关信息:
描述 | |
---|---|
可用于标准项目 | ✅ |
可用于 Serverless | ✅ |
可用于一体化 | ✅ |
包含独立主框架 | ❌ |
包含独立日志 | ❌ |
安装依赖
$ npm i @midwayjs/casbin@3 --save
或者在 package.json
中增加如 下依赖后,重新安装。
{
"dependencies": {
"@midwayjs/casbin": "^3.0.0",
// ...
},
}
启用组 件
首先,引入组件,在 configuration.ts
中导入:
import { Configuration } from '@midwayjs/core';
import * as casbin from '@midwayjs/casbin';
import { join } from 'path'
@Configuration({
imports: [
// ...
casbin,
],
importConfigs: [
join(__dirname, 'config')
]
})
export class MainConfiguration {
}
准备模型和策略
使用 Casbin 前需要定义模型和策略,这两个文件的内容 贯穿本文,建议先去官网了解相关内容。
我们以一个基础的模型为例,比如:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
g2 = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && g2(r.obj, p.obj) && r.act == p.act || r.sub == "root"
将其保存在项目根目录的 basic_model.conf
文件中。
以及包含下面内容的策略文件。
p, superuser, user, read:any
p, manager, user_roles, read:any
p, guest, user, read:own
g, alice, superuser
g, bob, guest
g, tom, manager
g2, users_list, user
g2, user_roles, user
g2, user_permissions, user
g2, roles_list, role
g2, role_permissions, role
将其保存在项目根目录的 basic_policy.csv
文件中。
配置模型和策略
这里我们的策略将以文件形式进行演示。
配置如下:
import { MidwayAppInfo } from '@midwayjs/core';
import { join } from 'path';
export default (appInfo: MidwayAppInfo) => {
return {
// ...
casbin: {
modelPath: join(appInfo.appDir, 'basic_model.conf'),
policyAdapter: join(appInfo.appDir, 'basic_policy.csv'),
}
};
}
装饰器鉴权
有多种形式来使用 Casbin,这里以装饰器作为示例。
定义资源
首先定义资源,比如放在 src/resource.ts
文件中,对应策略文件中对应的资源。
export enum Resource {
USERS_LIST = 'users_list',
USER_ROLES = 'user_roles',
USER_PERMISSIONS = 'user_permissions',
ROLES_LIST = 'roles_list',
ROLE_PERMISSIONS = 'role_permission',
}