使用Guardian client 批量创建用户并赋权

  其他常见问题
内容纲要

1. 概述

使用 Guardian Client 的 Java API,可以批量创建用户并授予权限,避免在 Guardian 界面上逐个手工操作。

本文提供一段已在 TDH 集群实测通过的完整代码:创建一批用户 → 授 GLOBAL ADMIN 权限 → 授表级 INSERT 权限 → 自动验证结果。脚本支持重复执行(已存在的用户自动跳过)。

2. 官方 Demo 简介

官方 demo 工程( guardian-demo 下载链接)包含两个模块,本文示例基于其中的 guardian-client-demo:

模块 / 样例类 功能
guardian-client-demo Guardian Client API 使用示例(本文内容)
guardian-migration-demo 将旧版 Guardian(ApacheDS)数据迁移至数据库的工具

guardian-client-demo 提供三个样例类,覆盖最常见的三类操作:

样例类 功能 核心方法
UserDemo 用户全生命周期管理 addUser 创建用户、updateUserPassword 修改密码(用户只能改自己的)、assign/deassign 加入或移出组/角色、createAccessToken/deleteAccessToken 管理 Access Token
UserPermissionDemo 服务权限管理 grant/revoke 赋权撤权、userPermissions 查询权限(含继承)、checkAccess 鉴权检查、getEffectiveService 获取有效服务名
QuotaDemo 配额管理 addQuota/updateQuota/deleteQuota 管理数据库存储配额、临时空间配额和 Furion 调度队列配额

官方 demo 的两种用法:

  • 直接跑样例:配置好 guardian-site.xml 后,运行各 Demo 的 main 方法即可体验完整流程(如 UserDemo 会依次执行创建→改密→赋权→查询→删除的演示,最后把演示用户删掉)。
  • 改造复用:把样例中的 API 调用抽取出来组装成自己的业务代码——本文第 4 节的批量脚本就是基于 UserDemo(创建用户)和 UserPermissionDemo(赋权)改写的。

3. 环境准备

  • JDK 1.8 及以上
  • 能访问 Guardian Server(默认端口 8380)
  • 一套具有用户管理权限的管理员账号(如 admin)

依赖 jar 包:

引用集群客户端目录 (推荐,最简单):TDH 客户端目录(如 /root/TDH-Client/inceptor/lib/)已包含全部依赖,编译运行时用通配符整目录引入即可,无需关心 jar 清单。

4. 配置文件 guardian-site.xml

连接参数(Server 地址、账号密码)统一放在 guardian-site.xml 配置文件中,与代码分离,换环境只改配置、不动代码。

在代码同级目录下创建 conf 目录,将配置文件放在 conf/guardian-site.xml:




    
    
        guardian.server.address
        172.18.131.172:8380;172.18.131.173:8380
    
    
    
        guardian.server.tls.enabled
        true
    
    
    
        guardian.connection.username
        admin
    
    
        guardian.connection.password
        123456
    

目录结构:

guardian_task/
├── conf/
│   └── guardian-site.xml     <- 连接配置,按环境修改
└── GuardianBatchDemo.java    <- 业务代码,无需改动

4. 批量创建用户并赋权(完整代码)

举例说明,创建user1/user2/user3这3个用户,并且赋权对quark1服务GLOBAL级的ADMIN权限,以及对default.emp_holo包的insert权限。

保存为 GuardianBatchDemo.java,只修改开头 5 个参数(用户清单、密码、服务名、库、表):

import io.transwarp.guardian.client.GuardianAdmin;
import io.transwarp.guardian.client.GuardianAdminFactory;
import io.transwarp.guardian.client.GuardianClient;
import io.transwarp.guardian.client.GuardianClientFactory;
import io.transwarp.guardian.common.model.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class GuardianBatchDemo {

  // ===== 1. 批量任务清单:按需增删用户名即可 =====
  static String[] USERS = {"user1", "user2", "user3"};
  static String PASSWORD = "123456";          // 需符合集群密码策略
  static String SERVICE = "quark1";           // 目标服务名
  static String DB = "default";
  static String TABLE = "emp_holo";

  public static void main(String[] args) throws Exception {
    // ===== 2. 连接 Guardian:无参工厂,自动读取 classpath 下的 guardian-site.xml =====
    GuardianClient client = GuardianClientFactory.getInstance();
    GuardianAdmin admin  = GuardianAdminFactory.getInstance();
    System.out.println("[OK] connected via guardian-site.xml");

    // ===== 3. 批量执行:创建用户 + 赋权 =====
    for (String user : USERS) {
      System.out.println("---- 处理用户 " + user + " ----");
      createUser(client, admin, user);
      grant(admin, user, Collections.singletonList("GLOBAL"), "ADMIN");
      grant(admin, user, Arrays.asList("TABLE_OR_VIEW", DB, TABLE), "INSERT");
    }

    // ===== 4. 批量验证 =====
    System.out.println("===== 权限验证结果 =====");
    for (String user : USERS) {
      boolean globalAdmin = client.checkAccess(user,
          new PermissionVo(SERVICE, Collections.singletonList("GLOBAL"), "ADMIN"));
      boolean tableInsert = client.checkAccess(user,
          new PermissionVo(SERVICE, Arrays.asList("TABLE_OR_VIEW", DB, TABLE), "INSERT"));
      System.out.println(user + " : GLOBAL ADMIN=" + globalAdmin + ", INSERT=" + tableInsert);
    }
  }

  // 创建用户;已存在则跳过(保证脚本可重复执行)
  static void createUser(GuardianClient client, GuardianAdmin admin, String user) throws Exception {
    try {
      client.getUser(user);                    // 能查到说明已存在
      System.out.println("[跳过] 用户 " + user + " 已存在");
      return;
    } catch (Exception e) {
      // 查询失败 = 用户不存在,继续创建
    }
    UserVo vo = new UserVo(user);
    vo.setUserPassword(PASSWORD);
    vo.setUserDescription("batch created by guardian client");
    admin.addUser(vo);
    System.out.println("[创建] 用户 " + user + " 创建成功");
  }

  // 单条赋权:path 为资源路径,action 为动作(全大写)
  static void grant(GuardianAdmin admin, String user, List path, String action) {
    try {
      admin.grant(EntityPermissionVo.UserPerm(user, new PermissionVo(SERVICE, path, action)));
      System.out.println("[赋权] " + user + " <- " + path + " " + action);
    } catch (Exception e) {
      System.out.println("[告警] " + user + " 赋权 " + action + " 失败(可能已存在): " + e.getMessage());
    }
  }
}

代码结构说明:

部分 作用
参数区(第 1 段) 用户清单、统一密码、目标服务/库/表,全部集中在这里修改
连接区(第 2 段) 无参工厂 getInstance(),自动加载 guardian-site.xml,代码内无地址密码
批量执行(第 3 段) 循环每个用户:先创建,再依次授予两条权限
批量验证(第 4 段) 循环用 checkAccess 回读,输出 true/false

5. 编译与运行

实测输出示例(首轮执行):

[OK] connected via guardian-site.xml
---- 处理用户 user1 ----
[创建] 用户 user1 创建成功
[赋权] user1 <- [GLOBAL] ADMIN
[赋权] user1 <- [TABLE_OR_VIEW, default, emp_holo] INSERT
---- 处理用户 user2 ----
...
===== 权限验证结果 =====
user1 : GLOBAL ADMIN=true, INSERT=true
user2 : GLOBAL ADMIN=true, INSERT=true
user3 : GLOBAL ADMIN=true, INSERT=true

重复执行时,已存在的用户会输出 [跳过] 用户 xxx 已存在,不会报错中断,权限重复授予无副作用。

6. 常见调整场景

需求 修改方法
增减用户数量 修改 USERS 数组即可
每个用户不同密码 去掉 PASSWORD 常量,改用 Map<String, String> 存放 用户名→密码
授权到整个库 把路径换成 Arrays.asList("DATABASE", "库名")
授权到其他服务 修改 SERVICE,如 inceptor1、argodbstorage
换权限动作 修改 action 参数,如 SELECT、UPDATE、DELETE(必须全大写)
批量撤销权限 把 grant(...) 换成同参数的 admin.revoke(...)
更换集群环境 只改 conf/guardian-site.xml,代码不动

这篇文章对您有帮助吗?

平均评分 0 / 5. 次数: 0

尚无评价,您可以第一个评哦!

非常抱歉,这篇文章对您没有帮助.

烦请您告诉我们您的建议与意见,以便我们改进,谢谢您。