- 数据分析
- 数据可视化
- 大数据
- 后端
【免费下载链接】zeppelin
Web-based notebook that enables>项目地址:https://gitcode.com/gh_mirrors/zeppelin1/zeppelin
导读
本文围绕 Apache Zeppelin 的**数据源授权(Data Source Authorization)**特性展开,讲解如何让每位登录用户使用自己的数据库账号(而非共享账号)访问 MySQL、Vertica、Presto 等数据源。读完本文你将掌握:在 Zeppelin UI 或通过 REST API 保存个人凭据的方法、凭据在conf/credentials.json中的存储与加密机制、凭据注入({entity.user}/{entity.password}占位符)与密码打码的原理,以及 JDBC 解释器如何基于这些凭据维护"每用户连接池"。
什么是数据源授权
数据源授权的核心思想是:认证与授权交由数据源自身完成。Zeppelin 并不代替数据库判断某个用户能访问什么表,而是把"以谁的账号登录数据库"这一环节交给用户自己决定,数据库再依据该账号的权限决定其可见范围。
典型场景如下:你已经在 Vertica 数据库中拥有一个账号,希望在 Zeppelin 中通过 JDBC 连接 Vertica 时使用这个账号,而不是让所有定义在conf/shiro.ini中的用户共享同一个数据库账号。此时只需要把自己的凭据(用户名 + 密码)保存到 Zeppelin,解释器即可在运行段落时自动使用它。
这条特性的演进始于 ZEPPELIN-828,由 Pull Request #860 实现;后续的社区管理解释器适配进度可关注 ZEPPELIN-1070(当前仓库中,JDBC 解释器已完整支持该机制,下文源码分析部分会给出依据)。
如何保存凭据信息
通过 UI 下拉菜单添加
在 Zeppelin 界面中打开 Credential 页面,即可在数据源下拉菜单中新增凭据。该交互由 credential.controller.js 实现:
- 页面初始化时会调用
GET /api/interpreter/setting拉取已配置的解释器名称列表,并为 Entity 输入框提供自动补全(angular.element('#entityname').autocomplete(...)),方便你直接选中某个解释器名称作为 Entity; - 新增凭据时通过
PUT /api/credential提交{entity, username, password}; - 列表中已有凭据可以就地编辑(仅可改用户名和密码,Entity 作为唯一键不可改)或删除(
DELETE /api/credential/{entity})。
Entity 的命名约定:Entity 是区分每组凭据的键。官方建议其命名约定为Interpreter Name(解释器名称),例如为 JDBC 解释器保存的凭据,Entity 就叫jdbc。这样解释器在运行时才能按命名规则找到对应的凭据(下文"JDBC 解释器如何按用户取凭据"一节会说明)。
用户名与密码:填写你自己的数据库账号,例如 JDBC 解释器要连的 MySQL 用户名和密码。
注:原文档中引用的界面截图(Credential 标签页与新增凭据表单)位于
docs/assets/themes/zeppelin/img/docs-img/目录下。由于该仓库的 docs 静态图片目录未包含这两张图,本文不强行配图,以文字说明代替。
凭据的归属与持久化
凭据按用户隔离存储,归属规则如下:
- 若已启用 Shiro 认证(参见 Shiro 认证指南),凭据保存在当前登录用户名下;
- 若未启用认证,凭据统一保存在
anonymous用户名下; - 所有凭据最终持久化到
conf/credentials.json(默认配置下;配置文件路径由zeppelin.credentials.persist与 conf 目录共同决定,见 ZeppelinConfiguration.java)。
持久化与加密由 Credentials.java 负责:
- 构造时读取
zeppelin.credentials.persist(默认true,见 ConfVars 定义 ZeppelinConfiguration.java),决定是否落盘; - 若配置了
zeppelin.credentials.encryptKey,则用 Encryptor.java 对文件内容做AES(AESEngine + ZeroBytePadding)加密后 Base64 编码再写入;解密时反向操作; - 保存/加载通过
ConfigStorage完成(支持本地文件系统等存储后端,见 LocalConfigStorage.java 与 FileSystemConfigStorage.java)。
因此,为保护生产环境中的数据库口令,建议在conf/zeppelin-site.xml中设置:
<property> <name>zeppelin.credentials.encryptKey</name> <value>your-encrypt-key</value> <description>Key used to encrypt credentials. If not set, credentials are stored in plain text.</description> </property>通过 REST API 管理凭据
凭据管理同样暴露为 REST API,由 CredentialRestApi.java 实现(@Path("/credential")),接口行为与 UI 页面一一对应:
GET /api/credential:返回当前用户的全部凭据(实体、用户名、密码);PUT /api/credential:新增/更新凭据,请求体 JSON 为{"entity": "jdbc", "username": "user", "password": "password"};任一字段为空时返回400 BAD_REQUEST;DELETE /api/credential:删除当前用户的全部凭据,不存在时返回404 NOT_FOUND;DELETE /api/credential/{entity}:删除指定 Entity 的凭据,不存在时返回404 NOT_FOUND。
完整的请求/响应示例可参考 Credential REST API 文档,例如保存一条凭据:
curl -X PUT -H "Content-Type: application/json" -d '{"entity":"jdbc","username":"mysql_user","password":"mysql_password"}' \ http://[zeppelin-server]:[zeppelin-port]/api/credential/需要说明的是,上述 REST API 文档中的示例以entity1/user1/password1等占位符形式给出,实际使用时应替换为真实 Entity 与账号口令。该 API 的测试用例位于 CredentialsRestApiTest.java,覆盖了凭据的存取与删除流程。
不同数据源的凭据使用差异
原文档针对三类常见数据源给出了差异化的说明:
- JDBC 解释器:需要维护每用户(per-user)的连接池。解释器的
interpret方法以用户字符串为参数,从对应用户的连接池中取出连接执行 JDBC 调用。具体实现见下文源码分析。 - Presto:如果 Presto 后端代码基于用户执行 HDFS 授权,那么可以不提供密码,凭据中可以只保存用户名。
- Vertica 与 MySQL:必须为用户存储密码信息,连接时以"用户名 + 密码"完成认证。
源码级原理解析
JDBC 解释器如何按用户取凭据
JDBCInterpreter.java 完整实现了凭据驱动的连接管理,关键逻辑如下:
- 解析当前用户:
getUser(context)优先取登录用户(Shiro principal);若为anonymous且解释器设置了default.user,则回退使用该属性值(JDBCInterpreter.java)。 - 解析 Entity 命名:
getEntityName(replName, propertyKey)规定——当解释器名恰为jdbc时,Entity 取属性键本身(default);否则取解释器名(JDBCInterpreter.java)。这正是官方建议"Entity 用解释器名"的代码依据。 - 读取凭据:
getUsernamePassword(context, entity)从context.getAuthenticationInfo().getUserCredentials()中按 Entity 取出UsernamePassword(JDBCInterpreter.java)。 - 每用户连接池:
setUserProperty(context)在解释器自身未配置default.user/default.password时,用当前用户凭据覆盖用户属性;随后createConnectionPool(url, user, properties)以jdbc:apache:commons:dbcp:default{user}这样的池名注册 DBCP 连接池(JDBCInterpreter.java、JDBCInterpreter.java),从而实现"一个用户一个连接池"。若找不到该用户的凭据,则关闭该用户连接池(closeDBPool(user))。
与此对应的官方文档说明见 JDBC 解释器文档:当default.user与default.password被删除(使用 X 按钮)后,解释器会转而使用用户在 Credential 页面保存的凭据建立连接。
凭据注入与密码打码
除 JDBC 解释器外,Zeppelin 还提供了通用的凭据注入机制,由 Paragraph.java 与 CredentialInjector.java 实现:
- 解释器属性
injectCredentials(常量定义见 Constants.java)控制是否启用注入,默认false; - 启用后,段落的脚本中形如
{entity.user}与{entity.password}的占位符会被替换为对应 Entity 的用户名与密码; - 注入的密码在返回结果中会被打码:
CredentialInjector.hidePasswords(ret)会把结果中出现的密码文本替换为###,避免凭据随结果泄露(覆盖 HTML / TEXT / TABLE 三种结果类型)。
例如,在段落中写:
%jdbc SELECT * FROM table WHERE creator = '{jdbc.user}'启用injectCredentials后,{jdbc.user}会被替换为当前用户在 Credential 页面中为 Entityjdbc保存的用户名。
凭据的数据模型
凭据按"用户 → 多个 Entity → 用户名/密码"三层组织:
- 顶层是 Credentials.java 持有的
Map<String, UserCredentials> credentialsMap,key 为用户名; - 每个
UserCredentials内部再按 Entity 维护多组UsernamePassword(其结构定义见 CredentialsInfoSaving.java 等org.apache.zeppelin.user包下的类); - 落到
conf/credentials.json时,大致形态为:
{ "credentialsMap": { "anonymous": { "userCredentials": { "jdbc": { "username": "mysql_user", "password": "mysql_password" } } } } }(以上 JSON 仅用于示意结构,实际字段名以CredentialsInfoSaving的 Gson 序列化结果为准。)相关单元测试见 CredentialsTest.java 与 EncryptorTest.java。
使用注意事项
- 先启用认证,再谈用户隔离:如果希望每位用户使用各自数据库账号,请先按 Shiro 认证指南 配置认证;否则所有凭据都归入
anonymous,也就失去了"个人凭据"的意义。 - Entity 命名保持一致:JDBC 解释器按
getEntityName规则(解释器名为jdbc时取default,否则取解释器名)查找凭据,保存凭据时 Entity 务必与解释器命名匹配。 - 密码存储安全:默认
zeppelin.credentials.persist=true会将凭据写入conf/credentials.json;生产环境应配置zeppelin.credentials.encryptKey启用 AES 加密,并保护好该密钥文件本身。 - 凭据注入按需开启:
injectCredentials默认关闭,只有确实需要在段落脚本中使用{entity.user}/{entity.password}占位符时才开启,且注意其会对返回结果中的密码做###打码处理。 - 数据库侧差异:Presto 在依赖 HDFS 授权时可只保存用户名;Vertica、MySQL 等必须同时保存用户名与密码。
- 适用范围:该特性最初面向自定义第三方解释器设计(ZEPPELIN-828),当前仓库中 JDBC 解释器已原生支持;使用其他解释器时请以其文档为准确认是否支持凭据读取。
总结
数据源授权让 Zeppelin 把"数据库认证与授权"交还给数据源本身,同时通过 UI、REST API 两层入口为用户提供个人凭据的保存、查询、更新与删除能力。其底层由Credentials(持久化 + AES 加密)、CredentialRestApi(REST 接口)、JDBCInterpreter(每用户连接池)与CredentialInjector(占位符注入 + 密码打码)协同完成。围绕该特性的核心代码与文档均可在当前仓库中定位到:datasource_authorization.md、Credentials.java、JDBCInterpreter.java、credential.controller.js。
- 数据分析
- 数据可视化
- 大数据
- 后端
【免费下载链接】zeppelin
Web-based notebook that enables>项目地址:https://gitcode.com/gh_mirrors/zeppelin1/zeppelin
相关推荐
Apache Zeppelin 数据源授权(Data Source Authorization)完全指南:让每个用户使用自己的数据库凭据
Apache Zeppelin 数据源授权(Data Source Authorization)完全指南:让每个用户使用自己的数据库凭据 数据源授权是 Apac
后端前端大数据数据分析Apache Zeppelin 数据源授权指南:凭据管理、注入机制与源码实现解析
Apache Zeppelin 数据源授权指南:凭据管理、注入机制与源码实现解析 数据源授权(Data Source Authorization)解决的是"多个
数据分析数据可视化大数据后端前端任务调度Apache Zeppelin 通用 JDBC Interpreter 使用指南:连接任意数据源、连接池调优与多数据库实战
Apache Zeppelin 通用 JDBC Interpreter 使用指南:连接任意数据源、连接池调优与多数据库实战 Apache Zeppelin 的
数据分析数据可视化大数据后端