## casbin介绍
详细介绍:
https://www.kancloud.cn/oldlei/casbin/1289454
`casbin`是由北大的一位博士生主导开发的一个基于`Go`语言的权限控制库。支持`ACL`,`RBAC`,`ABAC`等常用的访问控制模型。
`casbin`是`Golang`项目的强大而高效的开源访问控制库。 它支持基于各种访问控制模型实施授权。
`casbin`的核心是一套基于`PERM metamodel`(`Policy`,`Effect`,`Request`,`Matchers`)的`DSL`。`Casbin`从用这种`DSL`定义的配置文件中读取访问控制模型,作为后续权限验证的基础
## Casbin做了什么
* 支持自定义请求的格式,默认的请求格式为`{subject, object, action}`。
* 具有访问控制模型`model`和策略`policy`两个核心概念。
* 支持`RBAC`中的多层角色继承,不止主体可以有角色,资源也可以具有角色。
* 支持超级用户,如`root`或`Administrator`,超级用户可以不受授权策略的约束访问任意资源。
* 支持多种内置的操作符,如`keyMatch`,方便对路径式的资源进行管理,如`/foo/bar`可以映射到`/foo*`
## Casbin不做的事情
* 身份认证`authentication`(即验证用户的用户名、密码),`casbin`只负责访问控制。应该有其他专门的组件负责身份认证,然后由`casbin`进行访问控制,二者是相互配合的关系。
* 管理用户列表或角色列表。`Casbin`认为由项目自身来管理用户、角色列表更为合适,用户通常有他们的密码,但是`Casbin`的设计思想并不是把它作为一个存储密码的容器。而是存储`RBAC`方案中用户和角色之间的映射关系。
## 配置示例
### 模型与策略定制
```
//sub "alice"// 想要访问资源的用户.
//obj "data1" // 要访问的资源.
//act "read" // 用户对资源执行的操作.
# 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`和`Policy`的组成结构.`Policy effect`和`Matchers`则灵活的多,可以包含一些自定义的表达式比如我们要加入一个名叫`root`的超级管理员,就可以这样写:
~~~
[matchers]m = r.sub == p.sub && r.obj == p.obj && r.act == p.act || r.sub == "root"
~~~
又比如我们可以用正则匹配来判断权限是否匹配:
~~~
[matchers]m = r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)
~~~
### 具体规则设置
~~~
p, alice, data1, read
p, bob, data2, write
~~~
> 意思就是 alice 可以读 data1,bob 可以写 data2
```
//配置
[request_definition] //请求定义
r = sub, obj, act
[policy_definition] //策略定义,也就是*.cvs文件 p 定义的格式
p = sub, obj, act
[role_definition] //组定义,也就是*.cvs文件 g 定义的格式
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers] //满足条件
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
//请求用户与满足*.cvs p(策略)且满足g(组规则)且请求资源满足p(策略)规定资源
```
```
//policy策略
p, alice, /dataset1/*, GET //alice 用户有对 method为GET路径满足 /dataset1/*的访问权限 下面同理
p, alice, /dataset1/resource1, POST
p, bob, /dataset2/resource1, *
p, bob, /dataset2/resource2, GET
p, bob, /dataset2/folder1/*, POST
p, cathrin, /dataset2/resource2, GET
p, dataset1_admin, /dataset1/*, *
g, cathrin, dataset1_admin //cathrin用户属于dataset1_admin组,也就是dataset1_admin能访问的cathrin都能访问,反之不然
```
## 示例
> 模型与策略定制casbinmodel.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) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
~~~
> 具体规则设置casbinpolicy.csv
~~~
p, alice, /dataset1/*, GET
p, alice, /dataset1/resource1, POST
p, bob, /dataset2/resource1, *
p, bob, /dataset2/resource2, GET
p, bob, /dataset2/folder1/*, POST
~~~
## iris示例代码
~~~
package main
import (
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/middleware/basicauth"
"github.com/iris-contrib/middleware/casbin"
)
// $ go get github.com/casbin/casbin/v2@v2.17.0
// $ go run main.go
func newApp() *iris.Application {
app := iris.New()
casbinMiddleware, err := casbin.NewEnforcer("casbinmodel.conf", "casbinpolicy.csv")
if err != nil {
panic(err)
}
/* The Casbin authorization determines a request based on `{subject, object, action}`.
Please refer to: https://github.com/casbin/casbin to understand how it works first.
The object is the current request's path and the action is the current request's method.
The subject is extracted by the current request's ctx.User().GetUsername(),
you can customize it by:
1. casbinMiddleware.SubjectExtractor = func(ctx iris.Context) string {
// [...custom logic]
return "bob"
}
2. by SetSubject package-level function:
func auth(ctx iris.Context) {
casbin.SetSubject(ctx, "bob")
ctx.Next()
}
*/
app.Use(basicauth.Default(map[string]string{
"bob": "bobpass",
"alice": "alicepass",
}))
app.Use(casbinMiddleware.ServeHTTP)
app.Get("/", hi)
app.Get("/dataset1/{p:path}", hi) // p, alice, /dataset1/*, GET
app.Post("/dataset1/resource1", hi)
app.Get("/dataset2/resource2", hi)
app.Post("/dataset2/folder1/{p:path}", hi)
app.Any("/dataset2/resource1", hi)
return app
}
func main() {
app := newApp()
app.Listen(":8080")
}
func hi(ctx iris.Context) {
ctx.Writef("Hello %s", casbin.Subject(ctx))
// Note that, by default, the username is extracted by ctx.User().GetUsername()
// to change that behavior modify the `casbin.SubjectExtractor` or
// use the `casbin.SetSubject` to set a custom subject for the current request
// before the casbin middleware's execution.
}
~~~
- go入门
- go基础
- go语言介绍
- go语言主要特性
- Golang内置类型和函数
- init函数和main函数
- 下划线
- iota
- 字符串
- 数据类型:数组与切片
- 数据类型:byte、rune与字符串
- 变量的5种创建方式
- 数据类型:字典
- 指针
- 数据类型:指针
- 类型断言
- 流程控制:defer延迟执行
- defer陷进
- 异常机制:panic和recover
- go函数
- go方法
- go依赖管理
- 轻松搞懂goroot与gopath区别
- 使用go module导入本地包的方法教程详解
- 读取用户的输入
- 文件读写
- 文件拷贝
- 从命令行读取参数
- JSON 数据格式
- 4 种常见JSON 格式数据解码
- XML 数据格式
- 用 Gob 传输数据
- Go 中的密码学
- 学习资料建议
- 深入结构体
- 测试
- 单元测试
- 常用标准库
- fmt
- time
- flag
- log
- IO操作
- 文件读取
- strconv
- template
- http
- context
- json
- 从文件中反序列化json对象
- xml
- go proxy 设置
- 面向对象
- 结构体
- struct能不能比较
- 接口
- make和new的区别
- go进阶
- Slice底层实现
- 闭包与递归
- 空接口
- 反射
- 接口中的“坑”
- 反射三定律
- 结构体里的tag
- 并发编程
- 初识Go 协程:goroutine
- go协程:管道
- 任务和master-锁实现和通道实现
- 惰性生成器的实现
- runtime包
- Goroutine池
- 定时器
- 并发安全和锁
- Sync
- 原子操作(atomic包)
- GMP 原理与调度
- 爬虫案例
- 邮件发送
- Godoc 安装与使用
- test
- 如何测试
- 基准测试
- 数组与切片
- 结构体,方法和接口
- Map实现原理
- 自定义error
- 网络编程
- socket编程
- 互联网协议
- tcp 服务器
- tcp编程
- UDP编程
- TCP黏包
- http编程
- websocket编程
- 设计模式
- 设置模式6大原则
- 创建型模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 创建者模式
- 原型模式
- 单例模式
- 结构性模式
- 外观模式
- 适配器模式
- 代理模式
- 组合模式
- 享元模式
- 装饰模式
- 桥模式
- 行为型模式
- 中介者模式
- 观察者模式
- 命令模式
- 迭代器模式
- 模板方法模式
- 策略模式
- 状态模式
- 备忘录模式
- 解释器模式
- 职责链模式
- 访问者
- rpc
- Golang内存分配逃逸分析
- 面试题汇总
- 信号量的原理与使用
- 如何让在强制转换类型时不发生内存拷贝
- Go 如何利用 Linux 内核的负载均衡能力
- 性能优化:Go Ballast 让内存控制更加丝滑
- unsafe包详解
- go实战
- Go语言中编码规范
- json如何转为struct对象
- cobra
- 通过go mod模式创建cobra项目
- gorm
- gocache
- zap日志库
- echart
- web技术
- niugo
- context回调实现原理
- 认证与授权
- oauth2.0的4种实现方式
- IRIS
- 安装
- 入门
- 自定义http错误
- 基本HTTP API
- 中间件
- session
- websocket
- mvc
- cookie使用
- Casbin
- CORS跨域资源共享
- csrf防御
- jwt
- 限制HTTP请求次数的中间件Tollbooth
- 文件服务
- 基础使用
- 文件下载
- hero依赖注入与结构体转化
- hero基础
- 网络教程
- gin
- viper
- 在 5 分钟之内部署一个 Go 应用(Supervisor )
- go如何正常go get导入包
- 杂项
- 开源许可证
- 算法
- 洗牌算法
- 经典算法
- 基排序
- 冒泡排序
- 选择排序算法
- 二叉树
- 堆排序
- 快速排序
- 二分查找
- 图算法
- 有向图结构实现
- 拓扑排序
- 一致性hash算法
- 前缀树(字典树)
- 算法实现
- 斐波拉契
- 加密算法
- 简单可逆加密
- DH密钥交换(Diffie–Hellman key exchange)算法
- 代码实现
- Polybius密码(棋盘密码
- xor加密算法
- go应用
- 调试
- 构建并运行
- 包别名
- 类型转换
- error错误的2种处理方式
- 使用defer实现代码追踪
- 计算函数执行时间
- 通过内存缓存来提升性能
- make和new
- 关闭的channel可以读取数据吗
- 如何优雅的关闭channel
- channel应用场景
- map相关问题
- Go 面向包的设计和架构分层
- 设计模式实战
- 模板模式
- 责任链模式
- 组合模式实战
- 观察者模式实战
- 状态模式实战
- 区块链
- 构建一个区块链 -- Part 1: 基本原型
- 构建一个区块链 -- Part 2: 工作量证明
- 构建一个区块链 -- Part 3:持久化和命令行接口
- 从0到精通
- go常用命令
- 获取命令行参数
- http服务
- 基础
- struct 5种实例化
- md5
- Go Protobuf入门