ZooKeeper 权限管理

转载 2013年12月03日 23:47:53
这其中一个显而易见的问题就是权限:如果我的数据被别人动了怎么办?


方案一:采用ZooKeeper支持的ACL digest方式,用户自己定义节点的权限

        这种方案将zookeeper的acl和digest授权认证模式相结合。具体操作流程如下:

       

      可以把这个访问授权过程看作是用户注册,系统给你一个密码,每次操作使用这个用户名(appName)和密码. 于是就可以对应有这样权限管理系统,专门是负责进行节点的创建申请:包含“申请私有节点”和“申请公有节点”。这样一来,节点的创建都是由这个权限管理系统来负责了,每次申请完后,系统都会返回给你的一个key,格式通常是“{appName}:{password}”,以后你的任何操作都要在zk session 中携带上这个key,这样就能进行权限控制。当然,用户自己通过zk客户端进行path的创建也是可以的,只是要求他们要使用授权方式来进行zk节点的创建。(注意,如果使用zkclient,请使用 https://github.com/nileader/zkclient )

整个权限控制流程的代码测试,如下图所示,点击查看大图:(测试代码在这里


  1. package org.I0Itec.zkclient; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. import org.apache.zookeeper.WatchedEvent; 
  7. import org.apache.zookeeper.Watcher; 
  8. import org.apache.zookeeper.ZooDefs.Ids; 
  9. import org.apache.zookeeper.data.ACL; 
  10.  
  11. /** 
  12. * Description: ZooKeepre ACL权限控制 测试 
  13. * @author nileader / nileader@gmail.com 
  14. * @Date Feb 2, 2012 
  15. */ 
  16. public class DemoAuth implements Watcher { 
  17.  
  18. final static String SERVER_LIST = “127.0.0.1:4711″; 
  19.  
  20. final static String PATH = “/yinshi_auth_test”; 
  21. final static String PATH_DEL = “/yinshi_auth_test/will_be_del”; 
  22.  
  23. final static String authentication_type = “digest”; 
  24.  
  25. final static String correctAuthentication = “taokeeper:true”; 
  26. final static String badAuthentication = “taokeeper:errorCode”; 
  27.  
  28. static ZkClient zkClient = null
  29.  
  30. public static void main( String[] args ) throws Exception { 
  31.  
  32. List< ACL > acls = new ArrayList< ACL >( 1 ); 
  33. for ( ACL ids_acl : Ids.CREATOR_ALL_ACL ) { 
  34. acls.add( ids_acl ); 
  35.  
  36. try { 
  37. zkClient = new ZkClient( SERVER_LIST, 50000); 
  38. zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() ); 
  39. catch ( Exception e ) { 
  40. // TODO Auto-generated catch block 
  41. e.printStackTrace(); 
  42.  
  43. try { 
  44. zkClient.createPersistent( PATH, acls, “init content” ); 
  45. System.out.println( “使用授权key:” + correctAuthentication + “创建节点:” + PATH + “, 初始内容是: init content” ); 
  46. catch ( Exception e ) { 
  47. e.printStackTrace(); 
  48. try { 
  49. zkClient.createPersistent( PATH_DEL, acls, “待删节点” ); 
  50. System.out.println( “使用授权key:” + correctAuthentication + “创建节点:” + PATH_DEL + “, 初始内容是: init content” ); 
  51. catch ( Exception e ) { 
  52. // TODO Auto-generated catch block 
  53. e.printStackTrace(); 
  54.  
  55. // 获取数据 
  56. getDataByNoAuthentication(); 
  57. getDataByBadAuthentication(); 
  58. getDataByCorrectAuthentication(); 
  59.  
  60. // 更新数据 
  61. updateDataByNoAuthentication(); 
  62. updateDataByBadAuthentication(); 
  63. updateDataByCorrectAuthentication(); 
  64.  
  65. // 获取数据 
  66. getDataByNoAuthentication(); 
  67. getDataByBadAuthentication(); 
  68. getDataByCorrectAuthentication(); 
  69.  
  70. //删除数据 
  71. deleteNodeByBadAuthentication(); 
  72. deleteNodeByNoAuthentication(); 
  73. deleteNodeByCorrectAuthentication(); 
  74.  
  75. deleteParent(); 
  76.  
  77. zkClient.close(); 
  78.  
  79. /** 获取数据:采用错误的密码 */ 
  80. static void getDataByBadAuthentication() { 
  81. String prefix = “[使用错误的授权信息]“; 
  82. try { 
  83. System.out.println( prefix + “获取数据:” + PATH ); 
  84. zkClient = new ZkClient( SERVER_LIST, 50000); 
  85. zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() ); 
  86. System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) ); 
  87. catch ( Exception e ) { 
  88. System.err.println( prefix + “获取数据失败,原因:” + e.getMessage() ); 
  89.  
  90. /** 获取数据:不采用密码 */ 
  91. static void getDataByNoAuthentication() { 
  92. String prefix = “[不使用任何授权信息]“; 
  93. try { 
  94. System.out.println( prefix + “获取数据:” + PATH ); 
  95. zkClient = new ZkClient( SERVER_LIST, 50000); 
  96. System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) ); 
  97. catch ( Exception e ) { 
  98. System.err.println( prefix + “获取数据失败,原因:” + e.getMessage() ); 
  99.  
  100. /** 采用正确的密码 */ 
  101. static void getDataByCorrectAuthentication() { 
  102. String prefix = “[使用正确的授权信息]“; 
  103. try { 
  104. System.out.println( prefix + “获取数据:” + PATH ); 
  105. zkClient = new ZkClient( SERVER_LIST, 50000); 
  106. zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() ); 
  107. System.out.println( prefix + “成功获取数据:” + zkClient.readData( PATH ) ); 
  108. catch ( Exception e ) { 
  109. System.out.println( prefix + “获取数据失败,原因:” + e.getMessage() ); 
  110.  
  111. /** 
  112. * 更新数据:不采用密码 
  113. */ 
  114. static void updateDataByNoAuthentication() { 
  115.  
  116. String prefix = “[不使用任何授权信息]“; 
  117.  
  118. System.out.println( prefix + “更新数据: ” + PATH ); 
  119. try { 
  120. zkClient = new ZkClient( SERVER_LIST, 50000); 
  121. if( zkClient.exists( PATH ) ){ 
  122. zkClient.writeData( PATH, prefix ); 
  123. System.out.println( prefix + “更新成功” ); 
  124. catch ( Exception e ) { 
  125. System.err.println( prefix + “更新失败,原因是:” + e.getMessage() ); 
  126.  
  127. /** 
  128. * 更新数据:采用错误的密码 
  129. */ 
  130. static void updateDataByBadAuthentication() { 
  131.  
  132. String prefix = “[使用错误的授权信息]“; 
  133.  
  134. System.out.println( prefix + “更新数据:” + PATH ); 
  135. try { 
  136. zkClient = new ZkClient( SERVER_LIST, 50000); 
  137. zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() ); 
  138. if( zkClient.exists( PATH ) ){ 
  139. zkClient.writeData( PATH, prefix ); 
  140. System.out.println( prefix + “更新成功” ); 
  141. catch ( Exception e ) { 
  142. System.err.println( prefix + “更新失败,原因是:” + e.getMessage() ); 
  143.  
  144. /** 
  145. * 更新数据:采用正确的密码 
  146. */ 
  147. static void updateDataByCorrectAuthentication() { 
  148.  
  149. String prefix = “[使用正确的授权信息]“; 
  150.  
  151. System.out.println( prefix + “更新数据:” + PATH ); 
  152. try { 
  153. zkClient = new ZkClient( SERVER_LIST, 50000); 
  154. zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() ); 
  155. if( zkClient.exists( PATH ) ){ 
  156. zkClient.writeData( PATH, prefix ); 
  157. System.out.println( prefix + “更新成功” ); 
  158. catch ( Exception e ) { 
  159. System.err.println( prefix + “更新失败,原因是:” + e.getMessage() ); 
  160.  
  161. /** 
  162. * 不使用密码 删除节点 
  163. */ 
  164. static void deleteNodeByNoAuthentication() throws Exception { 
  165.  
  166. String prefix = “[不使用任何授权信息]“; 
  167.  
  168. try { 
  169. System.out.println( prefix + “删除节点:” + PATH_DEL ); 
  170. zkClient = new ZkClient( SERVER_LIST, 50000); 
  171. if( zkClient.exists( PATH_DEL ) ){ 
  172. zkClient.delete( PATH_DEL ); 
  173. System.out.println( prefix + “删除成功” ); 
  174. catch ( Exception e ) { 
  175. System.err.println( prefix + “删除失败,原因是:” + e.getMessage() ); 
  176.  
  177. /** 
  178. * 采用错误的密码删除节点 
  179. */ 
  180. static void deleteNodeByBadAuthentication() throws Exception { 
  181.  
  182. String prefix = “[使用错误的授权信息]“; 
  183.  
  184. try { 
  185. System.out.println( prefix + “删除节点:” + PATH_DEL ); 
  186. zkClient = new ZkClient( SERVER_LIST, 50000); 
  187. zkClient.addAuthInfo( authentication_type, badAuthentication.getBytes() ); 
  188. if( zkClient.exists( PATH_DEL ) ){ 
  189. zkClient.delete( PATH_DEL ); 
  190. System.out.println( prefix + “删除成功” ); 
  191. catch ( Exception e ) { 
  192. System.err.println( prefix + “删除失败,原因是:” + e.getMessage() ); 
  193.  
  194. /** 
  195. * 使用正确的密码删除节点 
  196. */ 
  197. static void deleteNodeByCorrectAuthentication() throws Exception { 
  198.  
  199. String prefix = “[使用正确的授权信息]“; 
  200.  
  201. try { 
  202. System.out.println( prefix + “删除节点:” + PATH_DEL ); 
  203. zkClient = new ZkClient( SERVER_LIST, 50000); 
  204. zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() ); 
  205. if( zkClient.exists( PATH_DEL ) ){ 
  206. zkClient.delete( PATH_DEL ); 
  207. System.out.println( prefix + “删除成功” ); 
  208. catch ( Exception e ) { 
  209. System.out.println( prefix + “删除失败,原因是:” + e.getMessage() ); 
  210.  
  211. /** 
  212. * 使用正确的密码删除节点 
  213. */ 
  214. static void deleteParent() throws Exception { 
  215. try { 
  216. zkClient = new ZkClient( SERVER_LIST, 50000); 
  217. zkClient.addAuthInfo( authentication_type, correctAuthentication.getBytes() ); 
  218. if( zkClient.exists( PATH ) ){ 
  219. zkClient.delete( PATH ); 
  220. catch ( Exception e ) { 
  221. e.printStackTrace(); 
  222.  
  223. @Override 
  224. public void process( WatchedEvent event ) { 
  225. // TODO Auto-generated method stub 
  226.  
  227.  

 

方案二、对zookeeper的AuthenticationProvider进行扩展,和内部其它系统A打通,从系统A中获取一些信息来判断权限

这个方案大致是这样:
1. A系统上有一份IP和appName对应的数据本地。
2. 将这份数据在ZK服务器上缓存一份,并定时进行缓存更新。
3. 每次客户端对服务器发起请求的时候,获取客户端ip进行查询,判断是否有对应appName的权限。限制指定ip只能操作指定 /appName znode。
4. 其它容灾措施。

个人比较两个方案:
1.方案一较方案二,用户的掌控性大,无论线上,日常,测试都可以由应用开发人员自己决定开启/关闭权限。 (方案一的优势)
2.方案二较方案一,易用性强,用户的使用和无权限基本一致。 (方案二的优势)
3.方案一较方案二更为纯洁。因为我觉得zk本来就应该是一个底层组件,让他来依赖其它上层的另一个系统?权限的控制精度取决于系统A上信息的准确性。 (方案一的优势)

另外附上 方案一 有权限和无权限对比压测TPS情况
测试条件
:三台ZK服务器:8核 JDK 1.6.0-06 四台zk客户端机器:5核 JDK1.6.0-21
测试场景:800个发布者,对应800个path,每个path 3个订阅者,共2400个订阅者。发布者发布数据,通知订阅者。
结论:权限控制对zk的TPS有一定的影响,但是还是保持在较高的水准(1.3w+),如图(点击查看大图):

 

 

Zookeeper ACL权限控制

Zookeeper使用ACL来控制访问Znode,ACL的实现和UNIX的实现非常相似:它采用权限位来控制那些操作被允许,那些操作被禁止。但是和标准的UNIX权限不同的是,Znode没有限制用户(us...
  • qianshangding0708
  • qianshangding0708
  • 2015年12月01日 11:54
  • 2966

zookeeper acl权限

ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表 zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,...
  • wuhenzhangxing
  • wuhenzhangxing
  • 2016年10月26日 16:59
  • 1801

zookeeper 权限概述

老样子,先上连接,第一个是淘宝综合业务平台的(前几个月还叫通用产品团队呢我记得) http://rdc.taobao.com/team/jm/archives/947,其实基本上需要的他这里都有...
  • JuliusRyan
  • JuliusRyan
  • 2013年01月31日 15:48
  • 5585

zookeeper ACL 权限验证

转载地址:http://www.wuzesheng.com/?p=2438 Access Control在分布式系统中重要性是毋庸置疑的,今天这篇文章来介绍一下Zookeeper中的Acces...
  • cainiaoxiaozhou
  • cainiaoxiaozhou
  • 2016年10月28日 11:42
  • 3613

zookeeper授权

第一步:cd到zookeeper的bin目录下执行: ./zkCli.sh -server localhost:2182 第二步:点击回车后,查看节点路径(例如查到的是dubbo): ls / 第三步...
  • ziruominglin
  • ziruominglin
  • 2017年07月05日 11:53
  • 364

zookeeper知识点一(创建带有权限的节点)

public class CreateNodeSyncAuth implements Watcher {     private static ZooKeeper zookeeper;     p...
  • wuliu_forever
  • wuliu_forever
  • 2016年07月28日 11:12
  • 737

ZooKeeper管理员指南——部署与管理ZooKeeper

大数据系列零基础由入门到实战视频 本帖最后由 pig2 于 2014-4-16 10:34 编辑 问题导读 ZooKeeper Server需要的jdk...
  • javastart
  • javastart
  • 2016年02月19日 17:10
  • 1455

(七)、ZooKeeper 授权验证

1.Zookeeper权限介绍 ZooKeeper 的权限管理亦即 ACL 控制功能通过 Server 、 Client 两端协调完成: Server 端: 一个 ZooKeeper 的节点( zno...
  • liuyuehu
  • liuyuehu
  • 2016年08月20日 23:47
  • 4713

Zookeeper客户端API之节点检查和权限控制(十一)

本篇博客介绍一下原生API的节点检查是否存在和节点操作权限控制。Zookeeper提供的方法的使用方式与前面增删改查操作类似,具体使用案例不再逐一用实例说明。 节点检查是否存在 原生API的提...
  • wo541075754
  • wo541075754
  • 2017年03月29日 07:46
  • 1003

zookeeper java调用及权限控制

zookeeper java调用 及 权限管理
  • main_xtgjfge
  • main_xtgjfge
  • 2014年06月25日 17:36
  • 3806
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZooKeeper 权限管理
举报原因:
原因补充:

(最多只允许输入30个字)