今天小编分享一篇关于Zookeeper权限控制&身份验证的内容,内容主要是对官方文档的翻译,在翻译过程中加入了小编自己的理解,并使用比较容易理解的方式进行表述和修饰,希望能帮各位开发小伙伴更新容易理解相关的内容;小编之前也分享过Zookeeper相关的文档,可参考如下链接:
- Zookeeper概览-官方文档翻译
- Zookeeper开发者指南——Zookeeper数据模型
- Zookeeper开发指南——Zookeeper会话
- Zookeeper开发指南——Zookeeper监听
Zookeeper使用ACLs进行访问控制(ZooKeeper access control using ACLs)
Zookeeper使用ACLs控制对节点的访问;ACL的实现与 UNIX 文件访问权限非常相似:它使用权限位来允许/禁止对节点的各种操作以及这些权限位适用的范围。但与标准 UNIX 权限不同,Zookeeper 节点不受“用户(文件所有者)”、“组”和“其他”三个标准范围的限制。Zookeeper 没有znode 所有者的概念。相反,ACL是指定一组 id 和与这些 id 关联的权限。
另外请注意,ACL仅适用于特定的znode,特别是不适用于子节点。例如:如果 /App 只能被 ip:172.16.16.1 读取,并且 /app/status的权限范围是所有人,那么任何人都可以读取 /app/status; ACL不是递归的。
ZooKeeper 支持插拔式的身份验证方案。使用scheme:expression格式来指定ID列表,其中 scheme 是ID对应的身份验证方案,有效的expression集合由scheme定义。 例如,ip:172.16.16.1 是使用ip方案来指定的ID, 其中主机地址为 172.16.16.1,表示该IP地址的主机有权限,而 digest:bob:password 表示了用户名称为bob的digest方案对应的ID。
当客户端连接到 ZooKeeper 并对其自身进行身份验证时,ZooKeeper 会将与客户端对应的所有 id 与客户端连接相关联。当客户端尝试访问节点时,这些 id 会根据 znode 的 ACL 进行检查。 ACL 由成对的 (scheme:expression, perms) 组成。表达式的格式会根据方案不同而有所不同。 例如, (ip:19.22.0.0/16, READ) 将 READ 权限授予 IP 地址以 19.22 开头的任何客户端。
ACL权限
Zookeeper支持以下的权限:
- CREATE: 开发者可以创建一个子节点
- READ: 开发者可以获取节点的数据以及子节点列表
- WRITE: 开发者可以为节点设置数据
- DELETE: 开发者可删除一个子节点
- ADMIN: 开发者拥有管理员角色,可以设置权限
CREATE 和 DELETE 权限已从 WRITE 权限中分离出来,以实现更精细的访问控制。 CREATE 和 DELETE 的场景如下:
希望 A 能够在 ZooKeeper 节点上进行设置,但不能CREATE 或DELETE 子节点。
CREATE:客户端通过在父目录中创建 ZooKeeper 节点来创建请求。开发者希望所有客户端都可以添加节点,但只有请求处理器可以删除。
此外,由于 ZooKeeper 没有文件所有者的概念,因此就有了ADMIN 权限。 在某种意义上,ADMIN 权限将实体指定为所有者。 ZooKeeper 不支持 LOOKUP 权限(对目录执行权限位以允许开发者在无法列出目录的情况下进行 LOOKUP)。 每个人都隐含地拥有 LOOKUP 权限。 这允许开发者统计一个节点,但仅此而已,没有其他用途。(问题是,如果你想在一个不存在的节点上调用 zoo_exists(),则没有权限校验)
ADMIN 权限依照 ACL规定,也有特殊的用法:为了检索 znode的 ACL,用户必须具有 READ 或 ADMIN 权限,但如果没有 ADMIN 权限,DIGEST哈希值将被屏蔽掉。
内置 ACL 方案Builtin ACL Schemes
Zookeeper包含以下内置方案:ZooKeeeper has the following built in schemes:
- world :有一个 id:anyone,代表任何人
- auth :auth是一种特殊方案,它忽略任何提供的表达式,而是使用当前用户、凭据和方案。 在持久化 ACL 时,ZooKeeper 服务器会忽略提供的任何表达式(无论是使用 SASL 身份验证的用户还是使用 DIGEST 身份验证的 user:password)。 但是,仍必须在 ACL 中提供表达式,因为 ACL 必须匹配格式 scheme:expression:perms。 提供此方案是为了方便,常见的用法是用户创建 znode ,然后将对该 znode 的访问限制为仅该用户。如果没有经过身份验证的用户,使用 auth 方案设置 ACL 将会失败。
- digest:DIGEST使用username:passowrd字符串生成MD5 哈希值,然后使用该哈希值作为ACL的ID身份。通过以明文形式发送username:password来完成身份验证。在 ACL 中使用时,表达式将是 username:password(密码是SHA1编码的base64) digest。
- ip 方案使用客户端主机IP 作为ACL的ID身份。ACL 表达式的格式为 addr/bits,其中 addr 的最高有效位与客户端主机 IP 的最高有效位相匹配。
- x509:x509 使用客户端X500 主体作为ACL ID 身份。 ACL 表达式是客户端的明确的 X500 主体名称。 使用安全端口时,客户端会自动进行身份验证,并设置 x509 方案的身份验证信息。
Zookeeper C语言客户端API
The following constants are provided by the ZooKeeper C library:
以下常量是由Zookeeper C语言客户端库提供:
- const int ZOO_PERM_READ; //能读取节点数据以及节点的子节点
- const int ZOO_PERM_WRITE;// 可以设置节点数据
- const int ZOO_PERM_CREATE; //可以创建子节点
- const int ZOO_PERM_DELETE;// 可以删除子节点
- const int ZOO_PERM_ADMIN; //能够执行set_acl()
- const int ZOO_PERM_ALL;// 上述全部标志位的“或”运算的结果
Zookeeper可插拔式的身份验证Pluggable ZooKeeper authentication
ZooKeeper 运行在各种不同的环境中,具有各种不同的身份验证方案,因此它具有完全可插拔的身份验证框架。即使是内置的身份验证方案也使用可插拔的身份验证框架。
要了解身份验证框架的工作原理,首先必须了解两个主要的身份验证操作。框架首先必须对客户端进行身份验证。这通常在客户端连接到服务器后立即完成,包括验证从客户端发送的或收集的关于客户端的信息并将其与连接相关联。框架处理的第二个操作是在 ACL 中查找与客户端对应的条目。 ACL 条目是 <idspec, permissions> 对。 idspec 可以是与连接关联的身份验证信息匹配的简单字符串,也可以是根据该信息进行计算的表达式。具体取决于身份验证插件的实现。这是身份验证插件必须实现的接口:
public interface AuthenticationProvider {
String getScheme();
KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte authData[]);
boolean isValid(String id);
boolean matches(String id, String aclExpr);
boolean isAuthenticated();
}
第一个方法getScheme返回标识插件的字符串。因为支持多种身份验证方法,所以身份验证凭证或idspec总是以scheme:作为前缀。ZooKeeper服务器使用认证插件返回的方案来确定该方案适用于哪些id。
当客户端给服务端发送与连接关联的身份验证信息时,调用handleAuthentication方法。客户端指定信息对应的方案,然后ZooKeeper服务器将身份认证信息传递给认证插件,插件的getScheme方法返回的方案与客户端传递的方案匹配。如果handleAuthentication的实现者确定信息是错误的,它通常会返回一个错误,否则使用cnxn.getAuthInfo().add(new Id(getScheme(), data))将身份验证信息与连接关联起来。
身份验证插件涉及到ACL的设置和使用。当为znode设置ACL时,ZooKeeper服务器会将数据项中的id部分传递给isValid(String id)方法。由插件来验证id是否具有正确的格式和结构。例如,ip:172.16.0.0/16是合法的id, 但是ip:host.com不是合法的id。如果新的ACL包含一个“auth”数据项,则使用isAuthenticated来查看是否应该将与连接相关联的方案的认证信息添加到ACL中。有些方案不应该包含在auth中。例如,如果指定了auth,则不应该将客户端的IP地址视为应该添加到ACL中的id。
Zookeeper检查ACL时会调用matches(String id, String aclExpr)。检查时需要将客户端的认证信息与相应的ACL数据项进行匹配。为了找到适用于客户端的数据项,ZooKeeper服务器将查找每个数据项的方案,如果客户端有该方案的认证信息,则 matches(String id, String aclExpr) 将被调用,其中id为由handleAuthentication方法添加到连接中的身份验证信息中的id,aclExpr为ACL数据项中的ID。身份验证插件使用自己的逻辑和匹配方案来确定id是否包含在aclExpr中
有两个内置的身份验证插件:ip 和 digest。 可以使用系统属性添加其他插件。在启动时,ZooKeeper 服务器将查找以“zookeeper.authProvider”开头的系统属性。并将这些属性的值作为身份验证插件的类名。 可以使用
-Dzookeeeper.authProvider.X=com.f.MyAuth 或在服务器配置文件中添加如下配置信息来设置这些属性:
authProvider.1=com.f.MyAuth
authProvider.2=com.f.MyAuth2
应注意确保属性上的后缀是唯一的。如果存在重复,则只会使用一个,例如
-Dzookeeeper.authProvider.X=com.f.MyAuth -Dzookeeper.authProvider.X=com.f.MyAuth2。
此外,所有服务器都必须定义相同的插件,否则使用插件提供的身份验证方案的客户端将无法连接到某些服务器。
3.6.0 中新增的内容:可插拔身份验证可以使用的另一种抽象。它提供了额外的参数。
public abstract class ServerAuthenticationProvider implements AuthenticationProvider {
public abstract KeeperException.Code handleAuthentication(ServerObjs serverObjs, byte authData[]);
public abstract boolean matches(ServerObjs serverObjs, MatchValues matchValues);
}
如果开发者扩展了
ServerAuthenticationProvider,而不是实现 AuthenticationProvider。 则 handleAuthentication() 和 matches() 方法将接收到额外的参数( ServerObjs 和 MatchValues)
- ZooKeeperServer Zookeeper服务实例
- ServerCnxn 当前连接
- path 当前正在操作的节点路径(如果没有,则是null)
- perm 操作的值或者是0 The operation value or 0
- setAcls ACLs列表,调用setAcl()方法进行设置
总结
以上就是小编为大家分享的内容;如果有翻译的不正确的地方,欢迎大家在评论区里面留言