ACL 查询
在 MaxCompute 中,可以通过 SecurityManager 执行 ACL(Access Control List)权限命令来管理访问控制。ACL 命令支持授权、撤销、查看权限、角色管理等操作,与在 MaxCompute Console 中执行权限 SQL 的效果一致。
前置条件
- 已完成 认证配置
- 已添加
odps-sdk-core依赖 - 当前账号需要有项目的 Admin 角色或相 应的管理权限
完整示例
以下示例演示如何通过 SDK 执行常见的 ACL 权限命令:
- Java
- Python
- Go
import com.aliyun.odps.Odps;
import com.aliyun.odps.OdpsException;
import com.aliyun.odps.account.AliyunAccount;
import com.aliyun.odps.security.SecurityManager;
import com.aliyun.odps.utils.StringUtils;
public class AclQueryExample {
public static void main(String[] args) throws OdpsException {
// 初始化 Odps 客户端
Odps odps = new Odps(new AliyunAccount("accessId", "accessKey"));
odps.setDefaultProject("my_project");
odps.setEndpoint("http://service.odps.aliyun.com/api");
// 获取 SecurityManager
SecurityManager sm = odps.projects().get().getSecurityManager();
// 1. 授予用户对表的 Select 权限
executeCommand(sm, "GRANT SELECT ON TABLE sales_data TO USER alice;");
// 2. 查看用户的权限
executeCommand(sm, "SHOW GRANTS FOR USER alice;");
// 3. 创建角色并绑定权限
executeCommand(sm, "CREATE ROLE analyst;");
executeCommand(sm, "GRANT SELECT ON TABLE sales_data TO ROLE analyst;");
executeCommand(sm, "GRANT analyst TO alice;");
// 4. 查看角色的权限
executeCommand(sm, "DESCRIBE ROLE analyst;");
// 5. 撤销权限
executeCommand(sm, "REVOKE SELECT ON TABLE sales_data FROM USER alice;");
// 6. 查看当前用户的权限
executeCommand(sm, "SHOW GRANTS;");
}
/**
* 执行 ACL 命令并输出结果
*/
private static void executeCommand(SecurityManager sm, String command) throws OdpsException {
System.out.println("执行: " + command);
// 提交命令
SecurityManager.AuthorizationQueryInstance instance = sm.run(command, false, null, null);
// 等待执行完成
while (!instance.isTerminated()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new OdpsException("命令执行被中断");
}
}
// 检查执行状态
if (instance.getStatus() == SecurityManager.AuthorizationQueryStatus.FAILED) {
throw new OdpsException("命令执行失败: " + instance.getResult());
}
// 输出结果
String result = instance.getResult();
if (StringUtils.isNullOrEmpty(result)) {
System.out.println("OK\n");
} else {
System.out.println(result + "\n");
}
}
}
from odps import ODPS
# 初始化 ODPS 客户端
odps = ODPS('access_id', 'access_key', 'my_project',
endpoint='http://service.odps.aliyun.com/api')
# 1. 授予用户对表的 Select 权限
odps.run_security_query("GRANT SELECT ON TABLE sales_data TO USER alice;")
# 2. 查看用户的权限
result = odps.run_security_query("SHOW GRANTS FOR USER alice;")
print(result)
# 3. 创建角色并绑定权限
odps.run_security_query("CREATE ROLE analyst;")
odps.run_security_query("GRANT SELECT ON TABLE sales_data TO ROLE analyst;")
odps.run_security_query("GRANT analyst TO alice;")
# 4. 查看角色的权限
result = odps.run_security_query("DESCRIBE ROLE analyst;")
print(result)
# 5. 撤销权限
odps.run_security_query("REVOKE SELECT ON TABLE sales_data FROM USER alice;")
# 6. 查看当前用户的权限
result = odps.run_security_query("SHOW GRANTS;")
print(result)
package main
import (
"fmt"
"log"
"github.com/aliyun/aliyun-odps-go-sdk/odps"
"github.com/aliyun/aliyun-odps-go-sdk/odps/account"
"github.com/aliyun/aliyun-odps-go-sdk/odps/security"
)
func main() {
acc := account.NewAliyunAccount("accessId", "accessKey")
odpsIns := odps.NewOdps(acc, "http://service.odps.aliyun.com/api")
odpsIns.SetDefaultProjectName("my_project")
// 获取 SecurityManager
sm := odpsIns.Projects().GetDefaultProject().SecurityManager()
// 1. 授予用户对表的 Select 权限
executeCommand(sm, "GRANT SELECT ON TABLE sales_data TO USER alice;")
// 2. 查看用户的权限
executeCommand(sm, "SHOW GRANTS FOR USER alice;")
// 3. 创建角色并绑定权限
executeCommand(sm, "CREATE ROLE analyst;")
executeCommand(sm, "GRANT SELECT ON TABLE sales_data TO ROLE analyst;")
executeCommand(sm, "GRANT analyst TO alice;")
// 4. 查看角色的权限
executeCommand(sm, "DESCRIBE ROLE analyst;")
// 5. 撤销权限
executeCommand(sm, "REVOKE SELECT ON TABLE sales_data FROM USER alice;")
// 6. 查看当前用户的权限
executeCommand(sm, "SHOW GRANTS;")
}
func executeCommand(sm security.Manager, command string) {
result, err := sm.RunQuery(command, false, "")
if err != nil {
log.Fatalf("命令执行失败: %+v", err)
}
if result != "" {
fmt.Println(result)
} else {
fmt.Println("OK")
}
}
代码说明
获取 SecurityManager
- Java
- Python
- Go
SecurityManager sm = odps.projects().get().getSecurityManager();
# Python SDK 中无需显式获取 SecurityManager,直接通过 odps 实例调用
odps.run_security_query("SHOW GRANTS;")
sm := odpsIns.Projects().GetDefaultProject().SecurityManager()
执行 ACL 命令
通过 run 方法提交 ACL 命令,返回一个异步查询实例:
- Java
- Python
- Go
SecurityManager.AuthorizationQueryInstance instance = sm.run(command, false, null, null);
result = odps.run_security_query(command)
instance, err := sm.Run(command, false, "")
参数说明:
command:要执行的 ACL SQL 命令useJson:是否以 JSON 格式返回结果(false表示普通文本格式)projectName:指定在哪个项目上下文中执行(null使用默认项目)supervisorToken:supervisor token(通常为null)
等待命令完成
ACL 命令是异步执行的,需要轮询等待完成:
- Java
- Python
- Go
while (!instance.isTerminated()) {
Thread.sleep(1000);
}
# Python SDK 的 run_security_query 会自动等待执行完成并返回结果
result = odps.run_security_query(command)
// 使用 WaitForSuccess 等待执行完成并获取结果
result, err := instance.WaitForSuccess()
获取执行结果
- Java
- Python
- Go
// 检查是否失败
if (instance.getStatus() == SecurityManager.AuthorizationQueryStatus.FAILED) {
System.err.println("失败: " + instance.getResult());
}
// 获取结果文本
String result = instance.getResult();
# run_security_query 直接返回结果,失败时抛出异常
try:
result = odps.run_security_query(command)
print(result)
except Exception as e:
print(f"失败: {e}")
// RunQuery 直接返回结果,失败时返回 error
result, err := sm.RunQuery(command, false, "")
if err != nil {
log.Fatalf("失败: %+v", err)
}
fmt.Println(result)
常见 ACL 命令
授权(GRANT)
-- 授予用户对表的权限
GRANT SELECT ON TABLE table_name TO USER user_name;
-- 授予角色对项目的权限
GRANT CreateInstance ON PROJECT project_name TO ROLE role_name;
-- 授予用户对 Package 的权限
GRANT Read ON PACKAGE project_name.package_name TO USER user_name;