Search code examples
tomcatcorsget-requesttomcat10jersey-3.0

Multiple consecutive slashes in the request causes 400 bad request error in Tomcat 10


I am upgrading my legacy project to Spring 6 and Tomcat 10. In that, normal requests are passed without any problem. But the requests like this:

http://localhost:9090/proactive-api/rest/order/fetchOrderLists/gokul//orderListing/////////All/50/0/true

are throwing cors error 400 bad request.The normal requests are like this:

http://localhost:9090/proactive-api/rest/ObpartnerInfo/gokul/gokul1

The only difference between these requests are the multiple consecutive slashes.
These requests worked fine on Tomcat 8 and Spring 5.

This is my security configuration in Spring 6.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfiguration {

    @Bean
    public static SecurityConfig securityConfig() {
        return new SecurityConfig();
    }

    private static final Logger LOG = LogManager.getLogger(SecurityConfig.class.getName());

    @Bean
    public SecurityFilterChain apiFilterChain(HttpSecurity http,
            AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter,
            OBOpenIdConnectFilter oBOpenIdConnectFilter, UnauthorizedEntryPoint unauthorizedEntryPoint)
            throws Exception {
        http.authorizeHttpRequests(authorize -> {
            try {
                authorize.requestMatchers("/openid-login").permitAll().requestMatchers("/rest/**").permitAll()
                        .anyRequest().authenticated();
            } catch (Exception e) {
                LOG.error(e);
                e.printStackTrace();
            }
        }).cors(cors -> cors.configurationSource(this::apiConfigurationSource)).csrf(csrf -> csrf.disable())
                .addFilterBefore(authenticationTokenProcessingFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(oBOpenIdConnectFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling(
                        exceptionHandling -> exceptionHandling.authenticationEntryPoint(unauthorizedEntryPoint));
        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(UserDetailsService mongoDBConnection,
            PasswordEncoder passwordEncoder) {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(mongoDBConnection);
        authenticationProvider.setPasswordEncoder(passwordEncoder);

        return new ProviderManager(authenticationProvider);
    }

    CorsConfiguration apiConfigurationSource(HttpServletRequest request) {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList(request.getHeader("origin")));
        configuration.setExposedHeaders(Arrays.asList("sdpauth, sdprefreshtoken"));
        configuration.setAllowedHeaders(Arrays.asList("*", "Content-Type", "Pragma", "Origin", "Authorization", "party",
                "X-XSRF-TOKEN", "X-Requested-With", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers",
                "Accept", "Access-Control-Allow-Credentials", "X-Auth-Token", "version", "cache"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD"));
        return configuration;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter(UserDetailsService userService) {
        return new AuthenticationTokenProcessingFilter(userService);
    }
}

I dont know exactly what change I need to make. in the CORS configuration as the other normal requests are working fine.

Edit: I did some debugging and found that request is not even reaching the spring layer. Tomcat takes the request as deceptive request routing or malformed and throws 400 bad request error. I also have a doubt on jersey 3 changes. But I couldn't find any error or warnings in log.

<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/10.1.18</h3></body></html>


Solution

  • I just found out that I used StrictHttpFirewall in my configuration. Instead I used DefaultHttpFirewall and it worked just fine.

    @Bean
    public HttpFirewall defaultHttpFirewall() {
        return new DefaultHttpFirewall();
    }