ZooKeeper 类的 addAuthInfo() 方法用于向 zookeeper 会话添加认证信息,以便在连接到 zookeeper 服务器时进行身份验证。在 zookeeper 中,可以使用不同的身份验证机制(例如digest、sasl 等)来保护 zookeeper 节点的访问权限,addAuthInfo() 方法允许客户端在连接到 zookeeper 服务器时提供相应的认证信息。
addAuthInfo() 方法的定义如下:
public void addAuthInfo(String scheme, byte[] auth)
参数说明:
scheme:表示身份验证方案,例如"digest"、"sasl"等。
auth:表示要提供的认证信息,通常是用户名和密码等凭据的字节数组。
下面示例演示 digest 身份验证方案,代码如下:
package com.hxstrive.zookeeper; import com.alibaba.fastjson.JSONObject; import org.apache.zookeeper.*; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Id; import org.apache.zookeeper.data.Stat; import org.junit.Before; import org.junit.Test; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.concurrent.CountDownLatch; /** * 添加授权信息 * @author hxstrive.com */ public class AuthInfoNode { private static ZooKeeper zooKeeper; @Before public void init() throws Exception { CountDownLatch countDownLatch = new CountDownLatch(1); zooKeeper = new ZooKeeper("127.0.0.1:2181", 2000, new Watcher() { public void process(WatchedEvent watchedEvent) { // 连接成功后添加认证信息 if(watchedEvent.getState() == Event.KeeperState.SyncConnected) { countDownLatch.countDown(); } } }); // 等待连接创建成功 countDownLatch.await(); } /** * 获取 digest 权限字符串,格式: * username:BASE64(SHA1(username:password)) * @param username 用户名 * @param password 密码 * @return 权限字符串 * @throws NoSuchAlgorithmException */ private String getDigestAuth(String username, String password) throws NoSuchAlgorithmException { // 创建 MessageDigest 实例并指定算法为 SHA-1 MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); // 将输入字符串转换为字节数组 byte[] inputData = (username + ":" + password).getBytes(); // 计算哈希值 byte[] sha1Hash = sha1.digest(inputData); return username + ":" + Base64.getEncoder().encodeToString(sha1Hash); } @Test public void createNode() throws Exception { // 获取授权字符串,test:PbXQT4DQMDcaYC1X0EY0B2RZCwM= // test:BASE64(SHA1(test:123456)) String authStr = getDigestAuth("test", "123456"); // 创建一个带权限的节点 List<ACL> acl = new ArrayList<>(); Id id = new Id("digest", authStr); acl.add(new ACL(ZooDefs.Perms.ALL, id)); String result = zooKeeper.create("/auth_node3", "new value".getBytes(), acl, CreateMode.PERSISTENT); System.out.println("创建节点:" + result); } @Test public void getNodeData() throws Exception { // 添加权限信息 zooKeeper.addAuthInfo("digest", "test:123456".getBytes()); System.out.println("添加认证信息"); // 获取节点内容 Stat stat = new Stat(); byte[] data = zooKeeper.getData("/auth_node3", false, stat); System.out.println("节点内容:" + new String(data)); System.out.println(JSONObject.toJSONString(stat)); //输出: //添加认证信息 //节点内容:new value //{"aversion":0,"ctime":1704092009921,"cversion":0,"czxid":386,"dataLength":9,"ephemeralOwner":0, // "mtime":1704092009921,"mzxid":386,"numChildren":0,"pzxid":386,"version":0} } }
更多关于授权的用法读者可以查看 “Zookeeper ACL(访问控制列表)” 章节。