1313import org .jeecg .common .system .base .controller .JeecgController ;
1414import org .jeecg .common .system .query .QueryGenerator ;
1515import org .jeecg .common .system .util .JwtUtil ;
16+ import org .jeecg .common .util .CommonUtils ;
1617import org .jeecg .common .util .RedisUtil ;
17- import org .jeecg .common .util .RestUtil ;
1818import org .jeecg .common .util .oConvertUtils ;
1919import org .jeecg .modules .openapi .entity .OpenApi ;
2020import org .jeecg .modules .openapi .entity .OpenApiAuth ;
@@ -184,7 +184,17 @@ public Result<?> call(@PathVariable String path, @RequestBody(required = false)
184184 httpHeaders .put ("X-Access-Token" , Lists .newArrayList (token ));
185185 httpHeaders .put ("Content-Type" ,Lists .newArrayList ("application/json" ));
186186 HttpEntity <String > httpEntity = new HttpEntity <>(json , httpHeaders );
187- url = RestUtil .getBaseUrl () + url ;
187+ //update-begin---author:scott ---date:20260429 for:【issues/9590】微服务nginx部署openApi接口访问不到-----------
188+ // originUrl 支持两种形式:
189+ // 1) 相对路径(如 /house/houseTest/list):拼接当前请求的 baseUrl;
190+ // 使用 CommonUtils.getBaseUrl(request)(而非 RestUtil.getBaseUrl()),
191+ // 可读取 X-Gateway-Base-Path 请求头,兼容微服务网关下的真实 base path
192+ // 2) 完整URL(http(s)://host:port/path):直接使用,适用于微服务模式下接口部署在其他微服务模块(如 erp 7003)的场景
193+ String lowerUrl = url .toLowerCase ();
194+ if (!lowerUrl .startsWith ("http://" ) && !lowerUrl .startsWith ("https://" )) {
195+ url = CommonUtils .getBaseUrl (request ) + url ;
196+ }
197+ //update-end---author:scott ---date:20260429 for:【issues/9590】微服务nginx部署openApi接口访问不到-----------
188198 UriComponentsBuilder builder = UriComponentsBuilder .fromHttpUrl (url );
189199 if (HttpMethod .GET .matches (method )
190200 || HttpMethod .DELETE .matches (method )
@@ -231,7 +241,9 @@ private String getToken(String USERNAME, String PASSWORD) {
231241 }
232242
233243 /**
234- * 校验原始接口路径是否合法:必须以 / 开头,不允许 // 和 .. 防止路径穿越
244+ * 校验原始接口路径是否合法:
245+ * - 相对路径:必须以 / 开头,不允许 // 和 .. 防止路径穿越
246+ * - 完整URL:仅允许 http/https 协议,禁止 file/ftp/gopher/jar/netdoc 等其它协议(用于微服务模式跨模块调用)
235247 */
236248 private void validOriginUrl (String originUrl ) {
237249 if (oConvertUtils .isEmpty (originUrl )) {
@@ -245,21 +257,33 @@ private void validOriginUrl(String originUrl) {
245257 } catch (Exception e ) {
246258 throw new JeecgBootBizTipException ("原始接口路径包含非法字符" );
247259 }
248- if (!decoded .startsWith ("/" )) {
249- throw new JeecgBootBizTipException ("原始接口路径必须以 / 开头" );
250- }
251- if (decoded .startsWith ("//" ) || decoded .startsWith ("/\\ " )) {
252- throw new JeecgBootBizTipException ("原始接口路径不能以 // 或 /\\ 开头" );
260+ //update-begin---author:scott ---date:20260429 for:【issues/9590】微服务nginx部署openApi接口访问不到-----------
261+ // 微服务部署时,OpenAPI 配置的接口可能位于其他微服务模块(如 erp 7003),允许 originUrl 直接配置完整 http(s) URL
262+ String lower = decoded .toLowerCase ();
263+ boolean isFullHttpUrl = lower .startsWith ("http://" ) || lower .startsWith ("https://" );
264+ if (!isFullHttpUrl ) {
265+ if (!decoded .startsWith ("/" )) {
266+ throw new JeecgBootBizTipException ("原始接口路径必须以 / 开头,或填写完整的 http(s) URL" );
267+ }
268+ if (decoded .startsWith ("//" ) || decoded .startsWith ("/\\ " )) {
269+ throw new JeecgBootBizTipException ("原始接口路径不能以 // 或 /\\ 开头" );
270+ }
271+ if (lower .contains ("://" ) || lower .startsWith ("file:" ) || lower .startsWith ("ftp:" ) || lower .startsWith ("gopher:" )
272+ || lower .startsWith ("jar:" ) || lower .startsWith ("netdoc:" )) {
273+ throw new JeecgBootBizTipException ("原始接口路径仅支持相对路径或 http(s) 完整URL" );
274+ }
275+ } else {
276+ // 即便是完整URL,也禁止其它危险协议(防止 http://x@file:/... 之类的绕过场景)
277+ String afterScheme = lower .substring (lower .indexOf ("://" ) + 3 );
278+ if (afterScheme .contains ("file:" ) || afterScheme .contains ("ftp:" ) || afterScheme .contains ("gopher:" )
279+ || afterScheme .contains ("jar:" ) || afterScheme .contains ("netdoc:" )) {
280+ throw new JeecgBootBizTipException ("原始接口路径不允许嵌套 file/ftp/gopher/jar/netdoc 等协议" );
281+ }
253282 }
254283 if (decoded .contains (".." )) {
255284 throw new JeecgBootBizTipException ("原始接口路径不能包含 .." );
256285 }
257- String lower = decoded .toLowerCase ();
258- if (lower .contains ("://" ) || lower .startsWith ("http:" ) || lower .startsWith ("https:" )
259- || lower .startsWith ("file:" ) || lower .startsWith ("ftp:" ) || lower .startsWith ("gopher:" )
260- || lower .startsWith ("jar:" ) || lower .startsWith ("netdoc:" )) {
261- throw new JeecgBootBizTipException ("原始接口路径不允许包含协议" );
262- }
286+ //update-end---author:scott ---date:20260429 for:【issues/9590】微服务nginx部署openApi接口访问不到-----------
263287 }
264288
265289 @ GetMapping ("/json" )
0 commit comments