Spring Boot 3.2.0无法处理含多斜杠URL,如何配置允许或拒绝?
Spring Boot 3.2.0 处理含多斜杠URL的配置方案
问题原因
你遇到的RequestRejectedException是由于Spring Security默认的StrictHttpFirewall会拦截包含//的URL,认为这是潜在恶意请求。
翻译后的异常信息
拒绝请求原因:请求因URL包含潜在恶意字符串"//"被拒绝 org.springframework.security.web.firewall.RequestRejectedException: 请求因URL包含潜在恶意字符串"//"被拒绝 at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlocklistedUrls(StrictHttpFirewall.java:535) at org.springframework.security.web.firewall.StrictHttpFirewall.getFirewalledRequest(StrictHttpFirewall.java:505) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:352) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
方案1:允许含多斜杠的URL请求
通过自定义StrictHttpFirewall并配置允许双斜杠,替换默认的防火墙规则:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.firewall.HttpFirewall; import org.springframework.security.web.firewall.StrictHttpFirewall; @Configuration public class SecurityFirewallConfig { @Bean public HttpFirewall allowDoubleSlashHttpFirewall() { StrictHttpFirewall firewall = new StrictHttpFirewall(); // 允许URL中的双斜杠 firewall.setAllowDoubleSlash(true); // 如果需要允许编码后的双斜杠(如%2F%2F),添加下面一行 // firewall.setAllowUrlEncodedDoubleSlash(true); return firewall; } }
如果使用Spring Security的SecurityFilterChain,需确保自定义的HttpFirewall被应用:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.firewall.HttpFirewall; @Configuration public class SecurityConfig { private final HttpFirewall allowDoubleSlashHttpFirewall; public SecurityConfig(HttpFirewall allowDoubleSlashHttpFirewall) { this.allowDoubleSlashHttpFirewall = allowDoubleSlashHttpFirewall; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // 应用自定义的HttpFirewall http.firewall(firewall -> firewall.httpFirewall(allowDoubleSlashHttpFirewall)); // 其他安全配置示例 http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); return http.build(); } }
方案2:直接拒绝并自定义异常响应
默认已拒绝此类请求,若需自定义拒绝后的响应内容(如返回JSON格式错误信息),可配置RequestRejectedHandler:
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.web.firewall.RequestRejectedException; import org.springframework.security.web.firewall.RequestRejectedHandler; import java.io.IOException; import java.nio.charset.StandardCharsets; @Configuration public class RequestRejectedConfig { @Bean public RequestRejectedHandler customRequestRejectedHandler() { return (HttpServletRequest request, HttpServletResponse response, RequestRejectedException ex) -> { response.setStatus(HttpStatus.BAD_REQUEST.value()); response.setContentType("application/json;charset=UTF-8"); response.getOutputStream().write("{\"code\":400,\"message\":\"请求URL格式非法\"}".getBytes(StandardCharsets.UTF_8)); }; } }
在SecurityFilterChain中配置该处理器:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http, RequestRejectedHandler customRequestRejectedHandler) throws Exception { http.exceptionHandling(handling -> handling.requestRejectedHandler(customRequestRejectedHandler)); // 其他安全配置示例 http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); return http.build(); }
注意:允许双斜杠可能带来路径遍历等安全风险,建议仅在确认业务需求且无安全隐患的情况下使用。
内容的提问来源于stack exchange,提问作者user352290
相关产品推荐
相关产品推荐

