部署带 ctx(/svc-hall)时 flow-center 按整路径签名与 FlowCallbackVerifyFilter 剥 ctx 后对不上 → 注册探活 401 → service_flow_reg 缺失 → 办件状态事件全丢。 本地裸地址(无 ctx)推导为空串,行为不变。新增 FlowCenterClientCallbackBasePathTest。
This commit is contained in:
@@ -145,6 +145,13 @@ public class FlowCenterClient implements FlowClient {
|
|||||||
if (eventTypes != null && !eventTypes.isEmpty()) {
|
if (eventTypes != null && !eventTypes.isEmpty()) {
|
||||||
body.put("eventTypes", eventTypes);
|
body.put("eventTypes", eventTypes);
|
||||||
}
|
}
|
||||||
|
// 申报本服务 context-path(从回调 URL path 段推导,去掉尾部 /callback/flow):
|
||||||
|
// 推送方按它剥离后再签应用签名,与本服务 AppAuthFilter/FlowCallbackVerifyFilter 剥
|
||||||
|
// contextPath 后的 target 对齐——本地裸地址(无 ctx)推导为空串,行为不变。
|
||||||
|
String basePath = deriveCallbackBasePath(callbackUrl);
|
||||||
|
if (basePath != null && !basePath.isEmpty()) {
|
||||||
|
body.put("basePath", basePath);
|
||||||
|
}
|
||||||
Map<?, ?> data = openCall.post(flowSpec, "/oapi/flow/callback/reg",
|
Map<?, ?> data = openCall.post(flowSpec, "/oapi/flow/callback/reg",
|
||||||
Collections.singletonMap("schId", String.valueOf(schId)), body, Map.class);
|
Collections.singletonMap("schId", String.valueOf(schId)), body, Map.class);
|
||||||
Object secret = data == null ? null : data.get("secret");
|
Object secret = data == null ? null : data.get("secret");
|
||||||
@@ -154,6 +161,30 @@ public class FlowCenterClient implements FlowClient {
|
|||||||
return String.valueOf(secret);
|
return String.valueOf(secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调 URL → 接收方 context-path:取 URL path 段去掉尾部 "/callback/flow"
|
||||||
|
* (如 /svc-hall/callback/flow → /svc-hall;裸地址 /callback/flow → 空串)。
|
||||||
|
* 包可见:契约测试冻结推导形态。
|
||||||
|
*/
|
||||||
|
static String deriveCallbackBasePath(String callbackUrl) {
|
||||||
|
if (callbackUrl == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String path = java.net.URI.create(callbackUrl.trim()).getPath();
|
||||||
|
if (path == null || path.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int idx = path.lastIndexOf("/callback/flow");
|
||||||
|
if (idx > 0) {
|
||||||
|
return path.substring(0, idx);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String trimTrailing(String s) {
|
private static String trimTrailing(String s) {
|
||||||
while (s.endsWith("/")) {
|
while (s.endsWith("/")) {
|
||||||
s = s.substring(0, s.length() - 1);
|
s = s.substring(0, s.length() - 1);
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package com.yunhai.svchall.service.impl;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 回调注册 basePath 推导契约:接收方 context-path 从回调 URL path 段去掉尾部
|
||||||
|
* /callback/flow 推导(部署带 ctx=签名对齐关键;本地裸地址=空串保持旧形态)。
|
||||||
|
* 2026-09-16 修复:注册漏带 basePath,flow-center 推送按整路径签名 →
|
||||||
|
* FlowCallbackVerifyFilter 剥 ctx 后对不上 → 401(本地无 ctx 掩盖)。
|
||||||
|
*/
|
||||||
|
class FlowCenterClientCallbackBasePathTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void derive_withContextPath() {
|
||||||
|
assertEquals("/svc-hall",
|
||||||
|
FlowCenterClient.deriveCallbackBasePath("http://svc-hall-service:10007/svc-hall/callback/flow"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void derive_bareLocalAddressIsEmpty() {
|
||||||
|
assertEquals("", FlowCenterClient.deriveCallbackBasePath("http://localhost:8086/callback/flow"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void derive_gatewayForm() {
|
||||||
|
assertEquals("/svc-hall",
|
||||||
|
FlowCenterClient.deriveCallbackBasePath("http://base.yunhaixingtong.com/svc-hall/callback/flow"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void derive_malformedOrNullSafe() {
|
||||||
|
assertEquals("", FlowCenterClient.deriveCallbackBasePath(null));
|
||||||
|
assertEquals("", FlowCenterClient.deriveCallbackBasePath(""));
|
||||||
|
assertEquals("", FlowCenterClient.deriveCallbackBasePath("::::"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user