Apache SeaTunnel Zeta Engine 的 Basic Auth 如何工作?
在排查 Apache SeaTunnel Zeta Engine 的 REST API 认证逻辑时,我们发现了一个常见但容易忽视的问题。 现象十分直接:Zeta Engine 已经正常启动,REST 服务也在监听指定端口,但当我们访问 /overview、/running-jobs、/job-inf
在排查 Apache SeaTunnel Zeta Engine 的 REST API 认证逻辑时,我们发现了一个常见但容易忽视的问题。
现象十分直接:Zeta Engine 已经正常启动,REST 服务也在监听指定端口,但当我们访问 /overview、/running-jobs、/job-info 等接口时,却收到以下响应:
HTTP/1.1 401 Unauthorized
初次遇到这种情况,大多数人首先会检查服务是否启动、端口是否正确、接口路径是否拼写错误。
然而,这类问题通常与 SeaTunnel Zeta Engine 的 Basic Auth 配置密切相关。
一旦 Basic Auth 被开启,客户端在调用 REST API 时就不能再像以前那样随意请求,必须在请求头中携带正确的认证信息。
本文将从 401 错误入手,详细解析 SeaTunnel Zeta Engine 的 Basic Auth 机制如何工作,以及客户端如何正确完成连接。
1. 现象描述:访问 Zeta REST API 返回 401
假设我们直接通过 curl 访问 Zeta Engine 的 REST API:
curl
如果 Basic Auth 未开启,该请求可以正常返回 Zeta Engine 的概要信息。
但一旦配置文件启用了 Basic Auth,而请求未包含认证信息,就会变成如下结果:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="SeaTunnel Web UI"
这表明请求已成功到达 Zeta Engine,但在进入实际的 REST Servlet 之前,被认证过滤器拦截。
总结起来就是:
Zeta Engine 正常运行
REST API 地址正确
但客户端未携带 Authorization 请求头
因此被 BasicAuthFilter 拦截并返回 401
Basic Auth 本身并不复杂,本质就是在 HTTP Header 中添加一段认证信息:
Authorization: Basic base64(username:password)
例如,用户名和密码均为 admin 时,客户端需要将:
admin:admin
进行 Base64 编码,然后放入 Authorization 请求头中。
2. 源码分析:BasicAuthFilter 如何拦截请求
SeaTunnel Zeta Engine 的 Basic Auth 核心逻辑位于 BasicAuthFilter 类中。
它实现了标准的 Servlet Filter:
public class BasicAuthFilter implements Filter {
private final HttpConfig httpConfig; public BasicAuthFilter(HttpConfig httpConfig) {
this.httpConfig = httpConfig;
}
}
Filter 的特点是:请求在进入真正的 Servlet 之前会先经过过滤器,因此认证逻辑统一在过滤器中完成,而不是分散在各个接口中。
核心代码位于 doFilter 方法中。
首先,它会判断 Basic Auth 是否开启:
if (!httpConfig.isEnableBasicAuth()) {
chain.doFilter(request, response);
return;
}
逻辑很直接——未开启认证,请求直接放行。
如果开启了,代码继续执行,开始读取 HTTP 请求头:
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;String authHeader = httpRequest.getHeader("Authorization");
接着判断请求头是否存在,以及是否以 "Basic " 开头:
if (authHeader != null && authHeader.startsWith("Basic ")) {
String base64Credentials = authHeader.substring("Basic ".length());
String credentials =
new String(Base64.decodeBase64(base64Credentials), StandardCharsets.UTF_8); final String[] values = credentials.split(":", 2);
}
这里执行了以下操作:从请求头获取 Authorization 内容,去掉 "Basic " 前缀,对剩余部分进行 Base64 解码,然后将解码后的字符串按冒号分割成用户名和密码。
例如,如果请求头为:
Authorization: Basic YWRtaW46YWRtaW4=
解码后得到:
admin:admin
然后将此结果与配置文件中的用户名密码进行比较:
if (username.equals(httpConfig.getBasicAuthUsername())
&& password.equals(httpConfig.getBasicAuthPassword())) {
chain.doFilter(request, response);
return;
}
如果两者匹配,请求放行。
如果请求头不存在、格式不正确或账号密码不匹配,则返回 401:
httpResponse.setHeader("WWW-Authenticate", "Basic realm="SeaTunnel Web UI"");
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
BasicAuthFilter 的整个流程可以总结为:
请求进入 Zeta REST 服务
↓
判断是否开启 Basic Auth
↓
未开启:直接放行
↓
已开启:读取 Authorization 请求头
↓
解析 Basic Auth 用户名和密码
↓
与配置中的 username/password 比较
↓
匹配成功:放行
匹配失败:返回 401 Unauthorized
3. 配置解析:enable-basic-auth、username、password 如何生效
与 Basic Auth 相关的核心配置主要有三个:

默认情况下:
enable-basic-auth = false
basic-auth-username = admin
basic-auth-password = admin
这里有一个容易被忽略的细节:虽然 basic-auth-username 和 basic-auth-password 默认值都是 admin,但只要 enable-basic-auth 未开启,它们就不会生效。
真正决定是否启用认证的开关就是:
enable-basic-auth
如果该值为 false,Zeta Engine 的 REST API 不会要求客户端携带认证信息。
如果为 true,所有被 BasicAuthFilter 保护的请求都必须通过认证。
一个示例配置如下:
seatunnel {
engine {
http {
enable-http = true
port = 8080 enable-basic-auth = true
basic-auth-username = "admin"
basic-auth-password = "admin"
}
}
}
开启后,普通请求就会失败:
curl
返回:
401 Unauthorized
正确的做法是:
curl -u admin:admin
或者显式在 Header 中传递:
curl
-H "Authorization: Basic YWRtaW46YWRtaW4="
这里的 YWRtaW46YWRtaW4= 就是 admin:admin 的 Base64 编码。
4. 客户端实践:如何通过 Authorization Header 连接
理解了服务端的认证逻辑后,客户端需要做的事情就很明确了。
只要 Zeta Engine 开启了 Basic Auth,客户端在请求 REST API 时必须携带:
Authorization: Basic base64(username:password)
如果使用 Java 代码访问,可以直接借助 Spring 的 HttpHeaders#setBasicAuth 方法。
例如:
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("admin", "admin", StandardCharsets.UTF_8);HttpEntity entity = new HttpEntity<>(headers);ResponseEntity
这段代码会自动生成 Basic Auth 请求头,无需手动进行 Base64 编码。
为了更通用,可以将认证逻辑封装成一个方法:
private void applyBasicAuth(HttpHeaders headers, String username, String password) {
if (username == null || username.trim().isEmpty()) {
return;
} if (password == null || password.trim().isEmpty()) {
return;
} headers.setBasicAuth(
username.trim(),
password,
StandardCharsets.UTF_8
);
}
然后每次请求 Zeta REST API 前统一调用:
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));applyBasicAuth(headers, username, password);
这样一来,无论是 GET 请求:
restTemplate.exchange(
"http://localhost:8080/running-jobs",
HttpMethod.GET,
new HttpEntity(null, headers),
List.class
);
还是 POST 请求:
restTemplate.exchange(
"http://localhost:8080/submit-job",
HttpMethod.POST,
new HttpEntity<>(configText, headers),
Map.class
);
都能统一携带认证信息。
这也就是客户端连接开启了 Basic Auth 的 Zeta Engine 时最核心的一点:REST API 本身没有变化,接口路径不变,只是请求头中必须多一个 Authorization 字段。
5. 补充:SeaTunnel Web 如何将认证可视化

前面介绍了 SeaTunnel Zeta Engine 层面的 Basic Auth 逻辑。
如果直接使用代码连接,需要自行维护 Zeta Engine 地址、端口、是否开启 Basic Auth、用户名和密码,并在每次请求 REST API 时将认证信息添加到请求头。
但许多用户希望更便捷,不想每次都手动拼接 Header 或测试接口。
因此,SeaTunnel Web 将这一步骤做成了可视化配置。新增一个 Zeta Engine 客户端时,页面上会显示以下配置项:
Client Name
Engine Type
Client Address
Client Port
Enable Basic Auth
Username
Password
用户开启 Basic Auth 并填写用户名和密码后,SeaTunnel Web 在请求 Zeta REST API 时会自动补充:
Authorization: Basic xxx
这样,当用户点击“测试连接”时,背后实际访问的仍是 Zeta Engine 的 /overview 接口,只是 SeaTunnel Web 帮用户处理了认证请求头。
保存客户端后,后续访问以下接口:
/overview
/running-jobs
/job-info
/finished-jobs
/submit-job
/submit-job/upload
/stop-job
/metrics
都可以基于已保存的客户端配置自动携带 Basic Auth。
这样做的好处是:SeaTunnel Zeta Engine 依然保持原有的 REST 认证机制,而 SeaTunnel Web 只是将认证配置可视化,用户无需关心 Authorization Header 的细节。
小结
SeaTunnel Zeta Engine 的 Basic Auth 逻辑并不复杂,但初次使用时确实容易引发 401 问题。
核心总结如下:
enable-basic-auth默认值为false,不开启时 REST API 无需认证。- 一旦开启
Basic Auth,Zeta Engine 会通过BasicAuthFilter拦截所有请求。 - 客户端必须在请求头中携带
Authorization: Basic xxx。 xxx是username:password的 Base64 编码。basic-auth-username和basic-auth-password默认值均为admin。- SeaTunnel Web 可将这个过程可视化,用户通过页面配置即可完成认证连接。
因此,再次遇到:
401 Unauthorized
不要急于怀疑 Zeta Engine 未启动,也不要只盯着端口和接口路径。
更值得优先确认的是:
- 是否开启了 enable-basic-auth
- 客户端是否携带了 Authorization 请求头
- 用户名和密码是否与配置一致
理清这些问题后,再看 SeaTunnel Zeta Engine 的 REST API 认证流程,就会清晰很多。
写在最后
SeaTunnel Web 是一个持续完善的可视化项目,旨在将数据源管理、Zeta Engine 连接、任务配置、运行日志和指标查看等常用功能做得更直观、更易上手。如果您也在学习 SeaTunnel,或者正在进行数据同步、数据集成相关工作,欢迎一起交流。
