Spring boot - POST method not allowed
Solution 1
So the problem was that one of the parameter was null. It has been solved adding required=null at the request parameter annotation, like that:
@RequestParam(value = "yourParamName", required = false)
this cause a 405, as defined here:
6.5.5. 405 Method Not Allowed
The 405 (Method Not Allowed) status code indicates that the method
received in the request-line is known by the origin server but not
supported by the target resource. The origin server MUST generate an
Allow header field in a 405 response containing a list of the target
resource's currently supported methods.
A 405 response is cacheable by default; i.e., unless otherwise
indicated by the method definition or explicit cache controls (see
Section 4.2.2 of [RFC7234]).
when the "target resource" are defined here:
Solution 2
In my case the endpoint had ssl on i.e. it was https
In Postman I by mistake was using http
http
will work fine for GET
s but for POST
s it returns a 405 method not allowed. It has to be https
if your endpoint expects it to be.
If you have request and response logging turned on in Spring the POST
endpoint in the above situation will log as follows:
[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,915Z (UTC+0) [http-nio-80-exec-6] DEBUG o.s.w.f.CommonsRequestLoggingFilter - Before request [GET /api/v1/my-app, client=1.2.3.4, user=aUser]
[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,915Z (UTC+0) [http-nio-80-exec-6] WARN o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
[2021-02-26T10:40:07+02:00] (my-app/fffffa343226e) 2021-02-26T08:40:07,916Z (UTC+0) [http-nio-80-exec-6] DEBUG o.s.w.f.CommonsRequestLoggingFilter - After request [GET /api/v1/my-app, client=1.2.3.4, user=aUser]
MarioC
Updated on February 26, 2021Comments
-
MarioC about 3 years
I'm dwelling with this problem... I have a Spring Boot application wit a S2S communication. I have a
@RestController
method which should accept POST request.This is the controller
@RestController public class PaymentRestController { @PostMapping("/util/paymentResponse") public void savePaymentResponse(@RequestParam boolean transaction_status, @RequestParam String usedToken, @RequestParam String transaction_message, @RequestParam String authCode, @RequestParam String transactionCode, @RequestParam String orderId, HttpServletRequest request) { //business logic } }
If i hit this link i get a 405 error, method not allowed
At first time i found that the request was blocked by the CSFR Filter which is enabled on the web application, so I have configured my security in this way
@Configuration @ComponentScan("it.besmart") @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter{ @Autowired @Qualifier("customUserDetailsService") UserDetailsService userDetailsService; @Autowired CustomSuccessHandler customSuccessHandler; @Autowired CustomAuthenticationFailureHandler customAuthenticationFailureHandler; @Autowired DataSource dataSource; private final static Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class); @Autowired public void configureGlobalService(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SwitchUserFilter switchUserFilter() { SwitchUserFilter filter = new SwitchUserFilter(); filter.setUserDetailsService(userDetailsService); filter.setSuccessHandler(customSuccessHandler); filter.setFailureHandler(customAuthenticationFailureHandler); return filter; } protected void configure(HttpSecurity http) throws Exception { logger.debug("Webapp security configured"); http .authorizeRequests() .antMatchers("/", "/home", "/contacts", "/faq", "/privacy", "/register", "/registrationConfirm", "/util/**", "/resendRegistrationToken","/park**", "/oauth/authorize", "/error") .permitAll() .antMatchers("/profile**", "/edit**","/payment**", "/plate**","/notification**", "/addPaymentMethod**", "/logout/impersonate**") .access("hasRole('USER') or hasRole('NOPAYMENT')") .antMatchers("/book**", "/manage**") .access("hasRole('USER')") .antMatchers("/admin**", "/login/impersonate**").access("hasRole('ADMIN')") .antMatchers("/updatePassword").hasAuthority("CHANGE_PASSWORD_PRIVILEGE") .and().formLogin().loginPage("/?login=login").loginProcessingUrl("/") .successHandler(customSuccessHandler).failureHandler(customAuthenticationFailureHandler).usernameParameter("email").passwordParameter("password").and().rememberMe().rememberMeParameter("remember-me").tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400).and().exceptionHandling().accessDeniedPage("/accessDenied") .and().csrf().ignoringAntMatchers( "/util**") .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")) .logoutSuccessUrl("/?logout=true").permitAll() .and().addFilterAfter(switchUserFilter(), FilterSecurityInterceptor.class); }
In this way i'm not getting the CSRF token exception, but still getting the 405 error. It's not even a problem of POST because if i change to GET the request and the mapping, i still take the 405 error... And if i try to send a POST, i see in the header response that the Allowed method is POST, if i send it in GET i see allowed method POST... weird
I don't know where to see...