Spring Boot项目在IntelliJ IDE中正常运行,但部署到Tomcat webapps目录后返回403无法访问
看起来你遇到了一个典型的Spring Boot WAR部署到外部Tomcat的权限问题,我来帮你一步步排查解决:
首先,先明确你的核心问题:本地IDE用内置Tomcat能正常访问/auth/welcome,但打包成WAR放到外部Tomcat后,即使这个接口配置了permitAll还是返回403。下面是几个大概率的原因和对应的解决方案:
1. 先排查JWT过滤器的问题
我注意到你配置了JwtAuthFilter并把它放在了UsernamePasswordAuthenticationFilter之前。这里很可能出问题:即使是permitAll的路径,这个过滤器还是会先执行,如果你的过滤器里没有对白名单路径做特殊处理,它会尝试解析请求中的JWT Token,而匿名请求没有Token,就会被过滤器拦截返回403。
解决方法:
在你的JwtAuthFilter的doFilterInternal方法里,先判断请求路径是否属于白名单(和SecurityConfig里的permitAll路径一致),如果是就直接放行:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 获取当前请求的相对路径(相对于上下文) String requestPath = request.getServletPath(); // 定义白名单,和SecurityConfig里的permitAll路径保持一致 List<String> whiteList = Arrays.asList("/auth/welcome", "/auth/addNewUser", "/auth/generateToken"); // 如果是白名单路径,直接放行,不做Token验证 if (whiteList.contains(requestPath)) { filterChain.doFilter(request, response); return; } // 下面是原来的JWT Token验证逻辑 // ... 你的原有代码 ... }
你可以先临时注释掉.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class);这一行,重新打包部署测试,如果能正常访问/auth/welcome,就说明确实是过滤器的问题,按照上面的方法修改即可。
2. 检查外部Tomcat的上下文路径匹配
虽然你的请求URLhttp://localhost:8081/logindemo/auth/welcome看起来是对的(WAR文件名是logindemo,上下文路径就是/logindemo),但可以确认一下Spring Security的路径匹配是否正确。
在Spring Boot中,Security的requestMatchers是基于Servlet上下文的相对路径,所以/auth/welcome是正确的,但你可以尝试更精确的匹配,比如指定请求方法:
.requestMatchers(HttpMethod.GET, "/auth/welcome").permitAll()
另外,也可以在SecurityConfig里开启调试日志,看看Spring Security是如何处理请求的:
在application.properties里添加:
logging.level.org.springframework.security=DEBUG
然后查看外部Tomcat的应用日志,会输出详细的请求拦截过程,比如哪个路径被匹配到了,有没有通过权限验证等信息,这能帮你快速定位问题。
3. 确认Spring Boot的Servlet初始化是否正常
你的LoginApplication已经继承了SpringBootServletInitializer并重写了configure方法,这是正确的,但可以检查一下外部Tomcat是否正确加载了这个类。你可以解压WAR文件,查看WEB-INF/classes下是否有LoginApplication.class,以及WEB-INF/lib下是否包含了所有必要的依赖(除了provided的Tomcat依赖)。
另外,确保打包命令用的是mvn clean package,避免旧的缓存文件影响。
4. 排查外部Tomcat的全局安全配置
虽然可能性不大,但可以检查一下外部Tomcat的conf/web.xml文件,看看有没有全局的安全约束配置,比如强制所有请求需要认证的规则。另外,确认conf/tomcat-users.xml里的用户有足够的权限访问应用(不过你已经能通过Tomcat Manager部署WAR,这个应该没问题)。
5. 临时放宽权限测试
如果上面的方法都没解决,可以临时把SecurityConfig里的权限配置改成所有请求都允许匿名访问,测试是否能正常访问:
.authorizeHttpRequests(auth -> auth .anyRequest().permitAll() )
如果这样能访问,说明之前的路径匹配或者权限配置有问题,再逐步调整回原来的配置,慢慢排查哪个环节出了问题。
按照上面的步骤一步步排查,应该能很快找到问题所在。如果还有疑问,可以把外部Tomcat的应用日志贴出来,能更精准地定位问题。
备注:内容来源于stack exchange,提问作者Sanket Saitawdekar

