☰
Apache Zeppelin Credential REST API 实战指南:凭据管理、加密持久化与注入机制
2026/10/10 1:53:04 网站建设 项目流程

本文围绕 Apache Zeppelin 的 Credential REST API 展开,系统讲解如何通过 HTTP 接口对数据源凭据进行新增、查询、删除管理,并深入其底层源码,剖析凭据的持久化、可选加密存储以及凭据在笔记执行时的注入与脱敏机制。读者阅读本文后,可以熟练调用/api/credential系列接口,并理解 Zeppelin 凭据体系与笔记执行的完整联动方式。

Overview:Zeppelin REST API 与 JSON 约定

Apache Zeppelin 提供了多组 REST API,用于远程交互与控制 Zeppelin 功能。所有 REST API 统一挂在以下基础端点之下:

http://[zeppelin-server]:[zeppelin-port]/api

其中zeppelin-port默认为8080(可在 zeppelin-site.xml.template 中调整)。Zeppelin 的 REST API 接收与返回的都是 JSON 对象,官方文档建议在浏览器中安装 JSON 格式化查看器(如 JSONView)以便直观阅读响应体。

以 Credential 接口为例,完整调用路径为:

http://[zeppelin-server]:[zeppelin-port]/api/credential

Zeppelin Credential 接口的注册入口位于 RestApiApplication.java,而具体的 REST 实现类为 CredentialRestApi.java。该类标注了@Path("/credential")、@Produces("application/json")与@Singleton,意味着所有 Credential 请求均以 JSON 格式收发,且 REST 资源为单例。它通过构造器注入了两个核心依赖:

  • Credentials:位于 zeppelin-zengine/src/main/java/org/apache/zeppelin/user/Credentials.java,负责凭据的存取、持久化与加密;
  • AuthenticationService:用于获取当前登录用户(authenticationService.getPrincipal()),保证凭据按用户隔离。

每个接口返回的 JSON 响应统一封装为{ "status", "message", "body" }结构,status为"OK"或错误码,body承载实际数据。

凭据数据模型:从 REST 请求到内存与磁盘

在深入接口之前,先理解 Zeppelin 的凭据数据模型。整体链路为:REST 请求 →CredentialRequestPOJO →UserCredentials→Credentials(内存 Map + 磁盘持久化)。

  • 请求消息体由 CredentialRequest.java 定义,包含entity、username、password三个字段,entity即凭据逻辑名称(后续在笔记中通过该名称引用)。
  • 单个用户的凭据集合由 UserCredentials.java 表示,内部使用ConcurrentHashMap<String, UsernamePassword>存放entity → (username, password)映射,并提供了getUsernamePassword、putUsernamePassword、removeUsernamePassword、existUsernamePassword等方法。
  • 全局凭据管理器 Credentials.java 维护Map<String, UserCredentials> credentialsMap,以用户名为键;所有操作前会通过loadCredentials()从磁盘重新加载,操作成功后通过saveCredentials()回写,从而保证多请求间的一致性与持久化。

持久化逻辑位于Credentials的loadFromFile()/saveToFile()方法:序列化使用带setPrettyPrinting()的 Gson,最终经由ConfigStorage.saveCredentials(jsonString)写入存储后端(默认文件系统)。当配置了加密密钥时,写入前会调用Encryptor.encrypt(),读取时调用Encryptor.decrypt(),实现落盘加密。

查询凭据列表:GET /api/credential

接口说明

项内容
DescriptionGET方法返回服务器上当前用户的全部凭据 key/value 对
URLhttp://[zeppelin-server]:[zeppelin-port]/api/credential
Success code200
Fail code500

示例 JSON 响应

{ "status": "OK", "message": "", "body": { "userCredentials": { "entity1": { "username": "user1", "password": "password1" }, "entity2": { "username": "user2", "password": "password2" } } } }

对应的后端实现是 CredentialRestApi.java 中的getCredentials():它通过authenticationService.getPrincipal()获取当前用户,再调用credentials.getUserCredentials(user)取出该用户的UserCredentials对象,封装进JsonResponse<>(Status.OK, uc)返回。若存储读取抛IOException,则返回 500。需要注意的是,getUserCredentials在用户尚无任何凭据时会返回一个空集合而非null,因此列表为空时body.userCredentials是一个空对象。

实际调用示例:

curl http://localhost:8080/api/credential

新增/更新凭据:PUT /api/credential/

接口说明

项内容
DescriptionPUT方法以新的属性创建(或覆盖)凭据信息
URLhttp://[zeppelin-server]:[zeppelin-port]/api/credential/
Success code200
Fail code500

示例 JSON 输入

{ "entity": "e1", "username": "user", "password": "password" }

示例 JSON 响应

{ "status": "OK" }

putCredentials()的实现流程(CredentialRestApi.java):

  1. 用 Gson 将请求体解析为CredentialRequest;
  2. 通过StringUtils.isAnyBlank(entity, username, password)校验三个字段,任一为空即返回400 BAD_REQUEST(这比文档中仅标注 500 更细致,具体见下节);
  3. 取当前用户,调用credentials.getUserCredentials(user)获取(或新建)UserCredentials;
  4. 执行uc.putUsernamePassword(entity, new UsernamePassword(username, password))写入内存;
  5. 调用credentials.putUserCredentials(user, uc),内部会先loadCredentials()再写入credentialsMap并saveCredentials()落盘;
  6. 成功返回{ "status": "OK" },写入磁盘抛IOException时返回 500。

实际调用示例:

curl -X PUT \ -H "Content-Type: application/json" \ -d '{"entity":"e1","username":"user","password":"password"}' \ http://localhost:8080/api/credential/

请求校验与 400 响应

虽然原文档将失败码标为 500,但从源码看,CredentialsRestApiTest.java 中的testInvalidRequest用例明确验证了四种非法输入均返回Status.BAD_REQUEST(400):entity为空、username为空、password为空、三者全为空。因此实际接口的失败语义为:参数缺失 → 400,存储异常 → 500。调用方在集成时应同时处理这两种失败码。

删除当前用户的全部凭据:DELETE /api/credential

接口说明

项内容
DescriptionDELETE方法删除当前用户的凭据信息
URLhttp://[zeppelin-server]:[zeppelin-port]/api/credential
Success code200
Fail code500

示例 JSON 响应

{"status":"OK"}

removeCredentials()的实现(CredentialRestApi.java)调用credentials.removeUserCredentials(user),其底层执行loadCredentials()→ 从credentialsMap移除该用户 →saveCredentials()。若该用户本来没有凭据(返回null),则响应404 NOT_FOUND;IOException时返回 500。测试用例testCredentialsAPIs验证了删除后body.userCredentials为空集合。

实际调用示例:

curl -X DELETE http://localhost:8080/api/credential

删除单个凭据实体:DELETE /api/credential/[entity]

接口说明

项内容
DescriptionDELETE方法删除给定的单个凭据实体
URLhttp://[zeppelin-server]:[zeppelin-port]/api/credential/[entity]
Success code200
Fail code500

示例 JSON 响应

{"status":"OK"}

removeCredentialEntity()通过 JAX-RS 的@Path("{entity}")与@PathParam("entity")捕获路径中的实体名(CredentialRestApi.java),然后调用credentials.removeCredentialEntity(user, entity)。底层 Credentials.java 的逻辑是:先loadCredentials(),若该用户不存在或该实体不存在(!uc.existUsernamePassword(entity)),返回false并响应404 NOT_FOUND;否则移除该实体并saveCredentials(),返回 200。测试用例同样覆盖了“删除不存在的实体返回 null”的场景。

实际调用示例:

curl -X DELETE http://localhost:8080/api/credential/e1

凭据持久化与可选加密配置

凭据是否落盘、是否加密,由 ZeppelinConfiguration.java 中的两个配置项控制:

配置项默认值说明
zeppelin.credentials.persisttrue是否将凭据持久化到存储后端;为false时凭据仅保存在内存中(重启即失效),Credentials构造器会跳过存储初始化
zeppelin.credentials.encryptKeynull(不加密)若配置了非空密钥,则凭据文件在写入前用Encryptor加密、读取时解密,实现敏感信息落盘加密

在 Credentials.java 的构造器中可以看到:只有conf.credentialsPersist()为true时才初始化storage与 Gson,并尝试从文件加载已有凭据;而encryptKey非空时才会创建Encryptor。若存储初始化失败,日志会提示 “Persistenz will be disabled” 并降级为纯内存模式。实际部署时,若采用默认的zeppelin.credentials.persist=true,凭据会以 JSON 形式(加密可选)保存到 Zeppelin 配置的存储后端。

凭据在笔记执行中的注入与脱敏

Credential REST API 管理的凭据,最终在笔记执行阶段被消费,核心组件是 CredentialInjector.java。它用两个正则表达式识别代码中的占位符:

  • \{([^\}]+)\.user\}:匹配{实体名.user},替换为对应凭据的用户名;
  • \{([^\}]+)\.password\}:匹配{实体名.password},替换为对应凭据的密码。

例如,为entity为db的凭据配置用户名myuser、密码mypass后,在解释器段落中书写:

import getpass print("user is {db.user}, password is {db.password}")

执行时CredentialInjector.replaceCredentials(code)会将代码中的占位符替换为真实凭据值;同时hidePasswords会把输出结果中出现过的密码统一替换为###(仅对 HTML、TEXT、TABLE 类型的输出生效),避免密码通过笔记结果泄露。这一机制在 CredentialInjectorTest.java 中有完整验证。

接口速查表与安全建议

方法路径功能成功码失败码
GET/api/credential列出当前用户全部凭据200500
PUT/api/credential/创建/更新凭据(entity、username、password)200400(参数缺失)/ 500
DELETE/api/credential删除当前用户全部凭据200404 / 500
DELETE/api/credential/[entity]删除指定凭据实体200404 / 500

安全实践要点:

  • 凭据按用户隔离(getPrincipal()),多用户场景下各自只能访问自己的凭据;
  • 生产环境建议配置zeppelin.credentials.encryptKey启用落盘加密,并妥善保管密钥;
  • REST API 默认随 Zeppelin 服务暴露,若部署在公网,应配合 Zeppelin 的认证(如 Shiro)与 HTTPS 使用,避免明文口令经网络传输;
  • 笔记输出中的密码会被自动脱敏为###,但用户名本身不会脱敏,仍需注意输出内容的信息控制。

本文档对应的原始接口说明见 docs/usage/rest_api/credential.md,REST 实现、凭据存储与注入逻辑可分别对照 CredentialRestApi.java、Credentials.java 与 CredentialInjector.java 深入研读,相关行为验证可参考 CredentialsRestApiTest.java。

  • 数据分析
  • 数据可视化
  • 大数据
  • 后端

【免费下载链接】zeppelin

Web-based notebook that enables>项目地址:https://gitcode.com/gh_mirrors/zeppelin1/zeppelin

点击查看免费下载
上一篇:FastAPI-SQLAlchemy实战项目:构建完整的用户管理系统
下一篇:终极流媒体服务器指南:5个实战技巧让go2rtc成为你的专业摄像头管理平台

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询