前提介绍
主体内容是想说关于Zookeeper权限控制。Zookeeper提供了ACL的权限控制。就是通过对zk上数据节点的ACL来控制客户端的数据节点的访问。Zookeeper提供了多种权限控制模式(Scheme),分别是world、auth、digest、ip和super。比较常用的就是digest。下面我结合SpringCloud Zookeeper官方文档的7.3章节来叙述我在开发过程中遇到的问题。
问题情况
spring-cloud-starter-zookeeper-discovery和spring-cloud-starter-zookeeper-config在使用的时候默认是使用没有权限控制的Zookeeper,当你使用有权限的Zooleeper就会报 NoAuth的Error。
解决过程
刚好7.3章节有讲如何addAuth.
@BoostrapConfiguration
public class CustomCuratorFrameworkConfig {
@Bean
public CuratorFramework curatorFramework() {
CuratorFramework curator = new CuratorFramework();
curator.addAuthInfo("digest", "user:password".getBytes());
return curator;
}
}
但是官方文档的设置把它放到7.x下面让我以为这是针对zookeeper的config单独来的,但是实际上这是全局的连接,知道原生zookeeper客户端建立连接的可能都知道。所以对于对于服务注册和配置中心都是生效的
spring.cloud.zookeeper.discovery.root=
spring.cloud.zookeeper.config.root=
这两个path执行zk命令 create [-s] [-e] path data acl
因为这两个/services和/config都是要一直存在所以-s 或者不填 create /services data digest:username:加密后(password):cdrwa
我一开始看到这里狠兴奋,以为官网很好,里面直接提供了CuratorFramework 的对象,只要在配置文件里面加上digest模式下的账号密码就好。但是事实没那么简单。CuratorFramework它是一个接口,官方的描述
You can add authentication information for Zookeeper ACLs by calling the addAuthInfo method of a CuratorFramework bean. One way to accomplish this is to provide your own CuratorFramework bean, as shown in the following example
通过调用Curatorframework Bean的addAuthInfo方法,可以为Zookeeper acl添加身份验证信息。
实现这一点的一种方法是提供您自己的Curatorframework Bean,如下例所示
就是要你去实现CuratorFramework接口并自己额外加一个addAuthInfo的方法。一开始因为在源码里面能直接搜索到CuratorFramework接口,没看到里面里面有addAuthInfo方法,一直在纠结这个方法来自哪。(英文的重要性)
但是我看到下面那一句
Consult the ZookeeperAutoConfiguration class to see how the CuratorFramework bean’s default configuration.
请参考ZookeeperAutoConfiguration类来了解Curatorframework Bean的默认配置。
所以我并没有去实现自己MyCuratorframeworkImpl。所以我去按照文档去实现第二种方法。但是也没有官方文档里面直接addAuthInfo方法但是在CuratorframeworkImpl里面看到
private ZookeeperFactory makeZookeeperFactory(final ZookeeperFactory actualZookeeperFactory) {
return new ZookeeperFactory() {
public ZooKeeper newZooKeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly) throws Exception {
ZooKeeper zooKeeper = actualZookeeperFactory.newZooKeeper(connectString, sessionTimeout, watcher