起因是安全团队反馈了一个漏洞,说通过公网域名访问内网中的一个SpringBoot服务的根路径,原本是域名的url变成了服务的内网的ip。

简略版的网络拓扑如下:

SpringBoot版本:2.2.5.RELEASE
server.servlet.context-path=/demo

通过域名访问的url如下:

https://domain.cn/demo

访问之后url转变为:

http://10.x.1/demo/

因为网关后面的SpringBoot服务在多个机器部署,转变后的url会变成其中的一台服务器的ip。

在nginx机器上看了下日志,发现请求有一个302重定向的过程,然后变成了SpringBoot的404页面,因为根路径没有对应的handler处理。

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Apr 10 23:59:59 CST 2025
There was an unexpected error (type=Not Found, status=404).
No message available

测试环境,在Chrome中打开F12调试模式,在Network下开启Preserve log,通过SpringBoot服务所在机器的ip和端口直接访问服务的根路径,同样有一个302重定向的过程

http://10.x.1/demo
会转变为
http://10.x.1/demo/

url在302重定向后,url后面拼接了一个 /

怀疑是不是SpringBoot有什么特殊处理,SpringBoot中是通过org.springframework.web.servlet.DispatcherServlet:doDispatch方法来分发处理请求的,本地调试项目发现doDispatch方法会进入两次,DispatcherServlet上面是tomcat容器了,看样子是容器里了,往上回溯调用链发现org.apache.catalina.mapper.Mapper:internalMapWrapper方法里有一段代码有关于重定向的逻辑,代码如下:

if(mappingData.wrapper == null && noServletPath &&
contextVersion.object.getMapperContextRootRedirectEnabled()) {
// The path is empty, redirect to "/"
path.append('/');
pathEnd = path.getEnd();
mappingData.redirectPath.setChars
(path.getBuffer(), pathOffset, pathEnd - pathOffset);
path.setEnd(pathEnd - 1);
return;
}

意思就是如果请求的路径是 "" ,那么将重定向到 / ,项目的 server.servlet.context-path=/demo,那么访问根路径,后面不加其它的url,正好就走到了这一个逻辑里面,看代码逻辑是有一个参数可以控制是否重定向的:mapperContextRootRedirectEnabled,这个是org.apache.catalina.core.StandardContext类中的一个配置参数,可以通过配置来修改

server.tomcat.redirect-context-root

贴一下它的注释:

Determines if requests for a web application context root will be
redirected (adding a trailing slash) by the Mapper. This is more
efficient but has the side effect of confirming that the context path is
valid.

修改参数的值为false,重启项目再次访问,不再出现302,而是直接到了404页面

server.tomcat.redirect-context-root=false

如果项目的context-path是 / 没有302重定向的过程。

有项目使用了undertow作为容器,但是看了下undertow的代码,发现没有提供类似的参数,后面写一篇文章来记录使用undertow作为容器时出现这样情况的解决方案。

tomcat作为老牌的容器,相较undertow还是有更多灵活的配置选项。

Spring Boot 使用 Tomcat 作为容器时访问根 context-path 302分析的更多相关文章

  1. spring boot 加载web容器tomcat流程源码分析

    spring boot 加载web容器tomcat流程源码分析 我本地的springboot版本是2.5.1,后面的分析都是基于这个版本 <parent> <groupId>o ...

  2. Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源

    Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...

  3. Spring Boot嵌入式的Servlet容器

    一.查看SpringBoot默认的嵌入式Servlet容器(默认使用的是tomcat) 在IDEA的项目的pom文件中按Ctrl + shift + Alt + U可以打开SpringBoot依赖的图 ...

  4. 17. Spring Boot 配置嵌入式Servlet容器

    一.如何定制和修改Servlet容器的相关配置 1.配置文件(ServerProperties): 优先级最高 server.port=8081 server.context‐path=/crud s ...

  5. spring boot(10)-tomcat jdbc连接池

    默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多.spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了 ...

  6. (7)Spring Boot web开发 --- servlet容器

    文章目录 配置嵌入式 Servlet 容器 注册 三大组件 使用其他 servlet 容器 使用外置的 `Servlet` 容器 配置嵌入式 Servlet 容器 Spirng Boot 默认使用自带 ...

  7. 【串线篇】spring boot配置嵌入式servlet容器

    SpringBoot默认使用Tomcat作为嵌入式的Servlet容器 问题? 一.如何定制和修改Servlet容器的相关配置 1.方法1修改和server有关的配置(ServerProperties ...

  8. Spring Boot入门(六):使用MyBatis访问MySql数据库(注解方式)

    本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 本篇博客我们讲解下在Spring Boot中使用MyBatis访问MySql数据库的简单用法. 1.前期 ...

  9. Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题

      (转载)Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题   这几天在用spring boot开发项目, 在开发的过程中遇到一个问题hibernate在执 ...

  10. Spring boot (12) tomcat jdbc连接池

    默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多,spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了 ...

随机推荐

  1. 历数java虚拟机GC的种种缺点

    Java通过垃圾收集器(Garbage Collection,简称GC)实现自动内存管理,这样可有效减轻Java应用开发人员的负担,也避免了更多内存泄露的风险. 如果你用过C++等需要手动管理内存的语 ...

  2. K-means 基本流程 Demo

    也是单纯搬个砖, 记个笔记, K-Means 最近是有在用的, 当然之前也有用的, 也是掉包来弄的, 已经很少会去自己写了, 这里的目的, 也是为了自己, 后面再遇到可以复制粘贴. 对, 情况就是这样 ...

  3. 【Java持久层技术演进全解析】从JDBC到MyBatis再到MyBatis-Plus

    从JDBC到MyBatis再到MyBatis-Plus:Java持久层技术演进全解析 引言 在Java企业级应用开发中,数据持久化是核心需求之一.本文将系统性地介绍Java持久层技术的演进过程,从最基 ...

  4. 用 AI 实现一个 GBK/GB2312 转 UTF-8 工具:轻松解决文本编码转换难题(附完整源码)

    用 AI 实现一个 GBK/GB2312 转 UTF-8 工具:轻松解决文本编码转换难题 在处理历史文件或与不同系统交互时,我们经常会遇到 GBK 或 GB2312 编码的文本文件.虽然现在 UTF- ...

  5. java springboot项目启动脚本,指定jdk、指定yml配置文件

    start.bat @echo off rem 设置Java路径,根据你的实际情况修改 set JAVA_PATH="./jdk-17.0.6/bin/java.exe" rem ...

  6. 有关Spring事务的传播机制

    这是一个非常常见的关于 Spring 事务传播机制 的问题,核心问题是: 在同一个类中,方法 A 调用方法 B,而方法 B 上有 @Transactional 注解.当调用方法 A 时,如果发生异常, ...

  7. 基于CentOS Stream 8的物联网平台深度优化方案

    系统架构全景图 图表 一.系统平台优化(CentOS Stream 8) 1. 系统基础配置 bash # 1. 系统更新与加固 sudo dnf update -y sudo dnf install ...

  8. 开源公开课丨ChengYing安装原理剖析

    一.直播介绍 之前的内容,我们为大家分享了ChengYing入门介绍,以及ChengYing部署Hadoop集群实战,本期我们为大家分享ChengYing安装原理. 本次直播我们将详细介绍ChengY ...

  9. Vertx 实现webapi实战项目(五)

    添加测试handler 一:定义上传json,注意,mId是必须的. 1 { 2 "mId": 101, 3 "name":"cddd", ...

  10. poi 酱放过的每日一歌

    整理一下 poi 酱放过的每日一歌,大概按照时间排序,如果有喜欢的大家可以参考一下. poi 酱喜欢什么样的歌 基本上从 \(2 \times 2\) 个维度考虑:唱腔(甜度.软度)和歌词(内容.与曲 ...