Restrict 是一个授权库,它提供了 RBAC 和 ABAC 模型的混合,允许定义简单的基于角色的策略,同时在需要时提供细粒度的控制。它可以帮助您在业务逻辑之外强制执行访问策略,并以方便的方式表达它们。
概念
Restrict 有助于以声明方式构建简单但功能强大的访问策略。为了做到这一点,我们引入了以下概念:
- Subject 主体- 想要执行某些操作的实体。需要实现Subject接口并提供指定角色的列表。主体通常是您域中的任何类型的用户或客户端。
- Resource 资源- 作为操作目标的实体。需要实现Resource接口并提供唯一的资源名称。资源可以由您域中的任何实体或对象实现。
- Action 动作——可以对给定的资源执行的任意操作。
- Context 上下文——包含验证访问权限所需的任何附加数据的值的映射。
- Condition 条件- 授予访问权限需要满足的要求。有几个内置条件,但可以添加任何自定义条件,只要它实现Condition接口即可。条件是表达更细粒度控制的方式。
基本用法
type User struct { |
策略
策略是对给定系统中应执行的访问规则的描述。它由一个角色映射组成,每个角色映射包含一组针对每个资源授予的权限,以及可在各种角色和资源下重复使用的权限预设。以下是策略的示例:
var policy = &restrict.PolicyDefinition{ |
访问请求
AccessRequest是一个描述有关访问的问题的对象——主体是否可以对特定资源执行给定的操作。
如果您只需要类似 RBAC 的功能,或者想要执行“初步”访问检查(例如,只检查主题是否可以读取给定的资源,而不考虑条件),则空的 Subject/Resource 实例就足够了。否则,应在授权之前检索主题和资源,并在 AccessRequest 中传递。
例如,在典型的后端应用程序中,主题(用户)可能来自请求上下文。资源(对话)可以从数据库中获取。整个授权过程以及主题/资源检索都可以在中间件功能中进行。
// ... manager setup |
除了空的 Subject/Resource 实例之外,还有两个辅助函数 -UseSubject()和UseResource(),当您不想创建空实例或给定的 Subject/Resource 未由域中的任何类型表示时,它们会很有用。在这种情况下,您可以使用:
accessRequest := &restrict.AccessRequest{ |
访问管理器
AccessManager负责实际验证。设置了适当的PolicyManager实例后(有关详细信息,请参阅PolicyManager 和持久性),您可以使用其Authorize方法来检查给定的AccessRequest。Authorize如果未授予访问权限,则返回错误,nil否则(表示没有错误并且授予访问权限)。
var policy = &restrict.PolicyDefinition{ |
验证和错误
由于Authorize方法依赖于各种操作,包括以条件形式提供的外部操作,因此其返回类型是通用error类型。但是,当错误是由实际策略验证(即未授予权限或不满足条件)导致时,Authorize将返回一个实例AccessDeniedError,该实例提供了有关拒绝访问原因的大量信息和上下文。它有助于轻松处理错误和调试。
如果错误是由策略验证引起的,则将根据请求中使用的验证策略返回。任何其他错误都将立即返回。
AccessDeniedError可以包含一个或多个潜在原因 - 类型的错误PermissionError,可通过Reasons属性访问。每个错误都PermissionError可以包含零个或多个ConditionNotSatisfiedError错误,可通过ConditionErrors属性访问。
可以使用类型断言来测试返回的错误。
err := manager.Authorize(accessRequest) |
目录