I have developed a Spring Boot application that includes a PATCH endpoint. The endpoint works perfectly in local and UAT environments, but there is an issue in the production environment where:
-
The endpoint is visible in the Swagger UI and the request URL is correct.
-
When I try to hit the API via Swagger, it results in a 404 error.
-
When I directly hit the endpoint URL from a browser, it returns a 405 Method Not Allowed error.
-
There are no error logs in the application logs when the issue occurs.
-
Other GET and POST endpoints are visible in Swagger and work fine in production.
What I Suspect:
- The 405 error when hitting the endpoint directly from the browser suggests that the server (or reverse proxy) may not be configured to handle PATCH requests.
- The 404 error in Swagger might indicate the request is not reaching the application correctly or is being blocked/redirected by middleware or proxy configurations.
- The fact that GET and POST endpoints work fine in production suggests the issue is specific to the handling of PATCH requests.
What I Need Help With:
- Why does the PATCH endpoint give different errors (404 in Swagger, 405 in direct browser calls)?
- Could this be related to the reverse proxy or server configuration (e.g., NGINX not allowing PATCH requests)?
- What additional steps should I take to debug this issue, given there are no error logs?
Here is my SecurityConfig file:
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutFilter;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final FilterChainExceptionHandler filterChainExceptionHandler;
@Bean
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'none';")
) //CSP implementation
)
.headers(headers -> headers
.frameOptions(HeadersConfigurer.FrameOptionsConfig::deny) // Deny framing to prevent clickjacking
)
.addFilterBefore(filterChainExceptionHandler, LogoutFilter.class)
.authorizeHttpRequests(requests -> requests
.anyRequest().permitAll()
);
return http.build();
}
}
Any help or suggestions would be greatly appreciated!