马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
迩来在看 Apache SeaTunnel Zeta Engine 的 REST API 认证逻辑时,遇到一个很范例的题目:
Zeta Engine 显着已经启动了,REST 服务也正常监听端口,但是访问 /overview、/running-jobs、/job-info 这些接口时,却返回了:- HTTP/1.1 401 Unauthorized
复制代码 如果只是第一次看到这个错误,很容易以为是服务没有启动、端口写错了,大概接口路径不对。
但实际上,这类 题目许多时间和 SeaTunnel Zeta Engine 的 Basic Auth 设置有关。
当 Zeta Engine 开启 Basic Auth 后,客户端再访问 REST API,就不能像之前一样直接哀求接口,而是必须在哀求头里带上精确的认证信息。
这篇文章就从这个 401 题目开始,简朴看一下 SeaTunnel Zeta Engine 的 Basic Auth 是怎么工作的,以及客户端应该怎样精确毗连。
1. 先说征象:访问 Zeta REST API 返回 401
假设我们直接访问 Zeta Engine 的 REST API:- curl http://localhost:8080/overview
复制代码 如果没有开启 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,客户端终极须要把:做 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 之前,会先颠末过滤器。
以是 Basic Auth 的认证逻辑并不是写在某一个详细接口里,而是在同一的过滤器中完成的。
核心代码在 doFilter 方法里。
起首,它会判定是否开启 Basic Auth:- if (!httpConfig.isEnableBasicAuth()) {
- chain.doFilter(request, response);
- return;
- }
复制代码 这段代码很关键。
如果没有开启 Basic Auth,哀求会直接放行:- chain.doFilter(request, response);
复制代码 也就是说,enable-basic-auth 没有开启时,REST API 不须要认证。
如果开启了 Basic Auth,代码会继承往下走,开始读取 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=
复制代码 解码后就是:然子女码会和设置中的用户名、暗码举行比力:- 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 没有开启,它们并不会收效。
真正决定是否启用认证的是:如果它是 false,Zeta Engine 的 REST API 不会要求客户端携带 Basic Auth。
如果它是 true,全部被 BasicAuthFilter 掩护的哀求都须要认证。
一个示例设置大概是如许:- seatunnel {
- engine {
- http {
- enable-http = true
- port = 8080
- enable-basic-auth = true
- basic-auth-username = "admin"
- basic-auth-password = "admin"
- }
- }
- }
复制代码 开启后,寻常哀求就会失败:- curl http://localhost:8080/overview
复制代码 返回:精确的访问方式应该是:- curl -u admin:admin http://localhost:8080/overview
复制代码 大概显式通报 Header:- curl \
- -H "Authorization: Basic YWRtaW46YWRtaW4=" \
- http://localhost:8080/overview
复制代码 这里的 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<Void> entity = new HttpEntity<>(headers);
- ResponseEntity<Map> response = restTemplate.exchange(
- "http://localhost:8080/overview",
- HttpMethod.GET,
- entity,
- Map.class
- );
复制代码 这段代码会主动天生 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<Void>(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 时,主动增补:如许用户点击“测试毗连”时,背后实际访问的照旧 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 可以把这个过程可视化,让用户通过页面设置完成认证毗连。
以是,当我们遇到:不要第一时间猜疑 Zeta Engine 没启动,也不要只看端口和接口路径。
更应该先确认:
- 是否开启了 enable-basic-auth
- 客户端是否带了 Authorization 哀求头
- 用户名和暗码是否和设置划一
明确了这一点,再看 SeaTunnel Zeta Engine 的 REST API 认证流程,就会清楚许多。
写在末了
SeaTunnel Web 是我正在一连完满的一个 SeaTunnel 可视化项目 ,渴望把数据源管理、Zeta Engine 毗连、使命设置、运行日记和指标检察这些常用本事,做得更直观、更容易上手。
项目地点: https://github.com/weifuwan/seatunnel-web
内里有体验地点、摆设文档、社区交换群。
如果你也在学习 SeaTunnel,大概正在做数据同步、数据集成干系的事故,也接待一起交换。
这里有一群上进的小搭档,也有一群爱分享的大佬。各人可以一起讨论题目、分享实践、完满文档,也一起把 SeaTunnel 这件事讲得更清楚、做得更好用。
原文链接:https://blog.csdn.net/weixin_41572727/article/details/161571362
|