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>
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();
}