升级至Spring Boot 3后所有页面返回403,触发JSP URI权限校验问题
问题原因及解决方案
核心原因
Spring Boot 3.2+(对应Spring Security 6.2+)默认修改了FilterChainProxy的DispatcherType处理规则:现在会对所有类型的请求(包括内部转发FORWARD)应用安全校验,而Spring Boot 2.7(Spring Security 5.7)默认只处理外部客户端发起的REQUEST类型请求。
你的场景中,控制器转发到/WEB-INF/jsp/my-page.jsp属于FORWARD请求,升级后会被Spring Security二次校验,但你的配置中没有匹配该路径的权限规则,因此返回403。
推荐解决方案
方案1:让Security仅处理外部请求(最合规)
通过配置限定Security过滤器只作用于外部客户端发起的REQUEST请求,忽略内部转发、包含等类型的请求,和Spring Boot 2.7的行为保持一致。
方式A:通过配置文件实现
在application.properties中添加:
spring.security.filter.dispatcher-types=REQUEST
或application.yml:
spring: security: filter: dispatcher-types: REQUEST
方式B:通过代码配置SecurityFilterChain
修改你的SecurityFilterChain Bean,显式指定过滤器仅处理REQUEST类型:
@Configuration @EnableWebSecurity @EnableMethodSecurity public class MyConfig { @Bean public SecurityFilterChain mySecurityChainFilterChain(HttpSecurity httpSecurity) throws Exception { // 指定过滤器仅处理外部REQUEST请求 httpSecurity.securityMatcher(new AntPathRequestMatcher("/**", null, EnumSet.of(DispatcherType.REQUEST))) .authorizeHttpRequests(requests -> requests .requestMatchers("/").permitAll() .requestMatchers("/my-page/**").authenticated() .requestMatchers("/my-page/admin/**").hasRole("ADMIN") ) .csrf().disable() .cors().disable() .authenticationManager(makeAuthenticationManager(httpSecurity)) .httpBasic(Customizer.withDefaults()); return httpSecurity.build(); } // 其他代码不变... }
方案2:临时允许WEB-INF路径(不推荐)
如果你只是临时解决问题,可以添加对/WEB-INF/**路径的权限放行,但这并非合规方案——因为WEB-INF目录本就不应该被外部直接访问,内部转发属于信任的内部操作,无需单独配置权限:
.authorizeHttpRequests(requests -> requests .requestMatchers("/").permitAll() .requestMatchers("/my-page/**").authenticated() .requestMatchers("/my-page/admin/**").hasRole("ADMIN") .requestMatchers("/WEB-INF/**").permitAll() // 临时 workaround,不推荐 )
验证说明
修改后,内部转发的JSP请求将不再经过Spring Security的权限校验,只会对外部客户端请求的路径(如/my-page/)进行校验,和你在Spring Boot 2.7中的行为一致,即可解决403问题。
内容的提问来源于stack exchange,提问作者moraleboost
相关产品推荐
相关产品推荐

