当前位置: 代码迷 >> 综合 >> ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表
  详细解决方案

ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

热度:105   发布时间:2023-09-15 06:49:42.0

https://www.cnblogs.com/yjmyzz/p/zookeeper-acl-demo.html


zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#sc_ZooKeeperAccessControl

总体来说,ZK的节点有5种操作权限:

CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,这5种权限简写为crwda(即:每个单词的首字符缩写)

注:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限


身份的认证有4种方式:

world:默认方式,相当于全世界都能访问

auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)

digest:即用户名:密码这种方式认证,这也是业务系统中最常用的

ip:使用Ip地址认证


Cli命令行下可以这样测试:


ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

通过getAcl命令可以发现,刚创建的节点,默认是 world,anyone的认证方式,具有cdrwa所有权限


继续捣鼓:

ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

先给/test增加了user1:+owfoSBn/am19roBPzR1/MfCblE的只读(r)权限控制,

说明:setAcl /test digest:用户名:密码:权限 给节点设置ACL访问权限时,密码必须是加密后的内容,这里的+owfoSBn/am19roBPzR1/MfCblE=,对应的原文是12345 (至于这个密文怎么得来的,后面会讲到,这里先不管这个),设置完Acl后,可以通过

getAcl /节点路径 查看Acl设置

然后get /test时,提示认证无效,说明访问控制起作用了,接下来:

addauth digest user1:12345 给"上下文"增加了一个认证用户,即对应刚才setAcl的设置

然后再 get /test 就能取到数据了

最后 delete /test 成功了!原因是:根节点/默认是world:anyone:crdwa(即:全世界都能随便折腾),所以也就是说任何人,都能对根节点/进行读、写、创建子节点、管理acl、以及删除子节点(再次映证了ACL中的delete权限应该理解为对子节点的delete权限)


刚才也提到了,setAcl /path digest这种方式,必须输入密码加密后的值,这在cli控制台上很不方便,所以下面这种方式更常用:


ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表

注意加框的部分,先用addauth digest user1:12345 增加一个认证用户,然后用 setAcl /test auth:user1:12345:r 设置权限,跟刚才的效果一样,但是密码这里输入的是明文,控制台模式下手动输入更方便。


好了,揭开加密规则:

static public String generateDigest(String idPassword)

        throws NoSuchAlgorithmException {

    String parts[] = idPassword.split(":", 2);

    byte digest[] = MessageDigest.getInstance("SHA1").digest(

            idPassword.getBytes());

    return parts[0] + ":" + base64Encode(digest);

}

就是SHA1加密,然后base64编码


代码使用:

zookeeper有一个很好用的客户端开源项目zkclient,官网地址为:http://github.com/zkclient ,其最新片0.7-dev已经支持ACL了(旧0.1版无此功能,所以推荐使用最新版),使用方法:

git clone https://github.com/sgroschupf/zkclient (把代码拉到本地)

修改

build.gradle 找到92行

uploadArchives {


    repositories.mavenDeployer {

        //repository(url: "file:///tmp/mavenRepo")

        repository(url: "http://172.21.129.56:8081/nexus/content/repositories/thirdparty/") {

            authentication(userName: admin, password: admin123)

        }

        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

        pom.project {

            name 'ZkClient'

            packaging 'jar'

            description 'A zookeeper client, that makes life a little easier.'

            url 'https://github.com/sgroschupf/zkclient'

            licenses {

                license {

                    name 'The Apache Software License, Version 2.0'

                    url 'http://www.apache.org/licenses/LICENSE-2.0.txt'

                    distribution 'repo'

                }

            }

            scm {

                url 'https://github.com/sgroschupf/zkclient'

                connection 'scm:git:git://github.com/sgroschupf/zkclient.git'

                developerConnection 'scm:git:https://github.com/sgroschupf/zkclient.git'

            }

            developers {

                developer {

                    id 'sgroschupf'

                    name 'Stefan Groshupf'

                }

                developer {

                    id 'pvoss'

                    name 'Peter Voss'

                }

                developer {

                    id 'jzillmann'

                    name 'Johannes Zillmann'

                }

            }

        }

    }

}

  相关解决方案