Zookeeper做爲配置管理服務,由於配置數據有很高的安全要求,須要有權限控制,客戶端須要進行登陸認證才操做(查看數據,修改數據,建立children znode等等)Zookeeper上面對應znode。java
1. 簡單的客戶端認證zkCli.sh 命令以下:node
[zk: localhost:2181(CONNECTED) 23] ls /tom Authentication is not valid : /tom
#添加認證以後,便可查看znode /tom [zk: localhost:2181(CONNECTED) 27] addauth digest tom:tom [zk: localhost:2181(CONNECTED) 28] ls /tom []
2. Zookeeper提供的認證方式apache
Zookeeper對權限的控制是znode級別的,不繼承即對父節點設置權限,其子節點不繼承父節點的權限。
world:有個單一的ID,anyone,表示任何人。
auth:不使用任何ID,表示任何經過驗證的用戶(驗證是指建立該znode的權限)。
digest:使用 用戶名:密碼 字符串生成MD5哈希值做爲ACL標識符ID。權限的驗證經過直接發送用戶名密碼字符串 的方式完成,
ip:使用客戶端主機ip地址做爲一個ACL標識符,ACL表達式是以 addr/bits 這種格式表示的。ZK服務器會將addr的前bits位與客戶端地址的前bits位來進行匹配驗證權限。 安全
3. auth認證方式bash
Perm:ALL, Id:("auth","") 即建立者擁有訪問權限。服務器
/auth的數據是「auth」, auth認證方式,讀寫權限。ide
[zk: localhost:2181(CONNECTED) 37] create /auth auth auth::rw Created /auth
查看/auth的訪問控制列表能夠看出須要經過digest模式用戶名密碼是tom/tom認證才能夠訪問,不對id作限制。編碼
[zk: localhost:2181(CONNECTED) 42] getAcl /auth 'digest,'tom:GcSMsIa2MmdW+zdSJKAv8gcnrpI= : rw
成功的認證:
spa
[zk: localhost:2181(CONNECTED) 0] ls /auth Authentication is not valid : /auth [zk: localhost:2181(CONNECTED) 1] addauth digest tom:tom [zk: localhost:2181(CONNECTED) 2] ls /auth []
失敗的認證:命令行
[zk: localhost:2181(CONNECTED) 2] addauth digest supper:admin [zk: localhost:2181(CONNECTED) 3] ls /auth Authentication is not valid : /aut
4.經過zkCli.sh 建立znode,並設置ACL
4.1 建立設置ACL的znode
圖1 - 用戶/密碼super/admin建立/supper:
圖2-用戶/密碼tom/tom建立/tom:
圖3-查看/supper和/tom的ACL:
4.2 使用以下代碼來生成用戶名和密碼的摘要:
java -cp $ZK_CLASSPATH \ org.apache.zookeeper.server.auth.DigestAuthenticationProvider amy:secret .... amy:secret->amy:Iq0onHjzb4KyxPAp8YWOIC8zzwY=
注:在啓動Zookeeper服務是指定
-Dzookeeper.DigestAuthenticationProvider.superDigest=super:<base64encoded(SHA1(password))
將啓用超級用戶,經過該supper:密碼認證的客戶端訪問將不受ACL列表限制。
5. 客戶端驗證
5.1驗證supper/admin
ZooKeeper zooKeeper1 = new ZooKeeper("192.168.88.153:2181", 10000, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event); } }); //zooKeeper1.addAuthInfo("digest", "supper:admin".getBytes()); Stat stat = new Stat(); byte[] supperData = zooKeeper1.getData("/supper", true, stat); System.out.println(new String(supperData) + "," + stat);
運行上面代碼,讀(r)znode "/supper" :
去掉註釋代碼,爲客戶端添加認證信息以後:
0,8589940093,8589940093,1439970090902,1439970090902,0,0,0,0,1,0,8589940093
數據是0,符合4中圖1設置的值。
5.2驗證tom/tom
ZooKeeper zooKeeper2 = new ZooKeeper("192.168.88.153:2181", 10000, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event); } }); zooKeeper2.addAuthInfo("digest", "tom:tom".getBytes()); stat = new Stat(); byte[] tomData = zooKeeper2.getData("/tom", true, stat); System.out.println(new String(tomData) + "," + stat);
結果似同5.1.
經過zkCli.sh客戶端鏈接,認證和讀取
6.使用zkCli.sh 驗證acl(點擊查看大圖)
Zookeeper提供的權限信息表:
權限 | 描述 | setAcl中的簡寫 |
write | 可以設置znode的值 | w |
read | 可以讀取znode的值和列出它的children znode | r |
create | 可以建立children znode | c |
delete | 可以刪除children znode | d |
admin | 可以執行setAcl即設置訪問控制列表 | a |
all | 全部權限 | wrcda |
7:注意問題:
7.1 經過zkCli.sh設置acl的格式是scheme:id:perm,perm的寫法是簡寫字母鏈接,如讀寫權限rw和Linux的文件系統的權限類似。有些版本多是:READ|WRITE, 因此須要注意命令行提示信息。
7.2 經過zkCli.sh設置acl時,scheme是digest的時候,id須要密文,具體生成參見文4.2
7.3 經過Zookeeper的客戶端編碼方式添加認證,digest對應的auth數據是明文,參見文5.1
8.Zookeeper認證的擴展
實現AuthenticationProvider接口提供自定義的認證方式。
org.apache.zookeeper.server.auth.AuthenticationProvider
好比自定義實現AuthenticationProvider類是secondriver.MyProvier,能夠經過兩種方式註冊Zookeeper認證體系中去。
第一種:啓動Zookeeper服務是經過-Dzookeeper.authPorivder.X=secondriver.MyProvider
第二種:添加到配置文件(zoo.conf)中如:
zookeeper.authProvider.1=secondriver.MyProvider
注:上面X是對authProvider實現提供編號用來區別不一樣的authProvider。