Jake Miller Jake Miller - 3 months ago 61
Java Question

POST request says "405 GET not supported" with Spring security enabled

When I enable Spring security using a class which extends

WebSecurityConfigurerAdapter
, I receive this error when I send
POST
requests:

o.s.web.servlet.PageNotFound : Request method 'GET' not supported


I get an error that
GET
is not allowed when I'm sending
POST
... I've been unable to figure this out for hours.

It works perfectly fine if I comment out
@EnableWebSecurity
in my main class and the
WebSecurityConfigrerAdapter
class as shown below:

@Configuration
@EnableResourceServer
@Order(-20)
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

private final AuthenticationManager authenticationManager;

@Autowired
public CustomWebSecurityConfigurerAdapter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.parentAuthenticationManager(authenticationManager);
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/css/**", "/js/**", "/images/**", "/fonts/**", "/videos/**")
.permitAll()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.authorizeRequests()
.antMatchers("/", "/join", "/login", "/about", "/contact", "/index.html")
.permitAll()
.and().authorizeRequests()
.anyRequest().authenticated()
.and().exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/"))
.and()
.logout().logoutSuccessUrl("/index.html").permitAll()
.and()
.csrf().disable();
}

}


Here's my Spring controller by the way, if needed:

@RequestMapping(value = "/login", method = RequestMethod.POST)
public ResponseEntity<BusinessUser> login(@RequestBody BusinessUser inputUser) {
BusinessUser requestedUser = businessUserService.findByUsername(inputUser.getUsername());
if(requestedUser != null)
if(BCrypt.checkpw(inputUser.getPassword(), requestedUser.getPassword()))
return new ResponseEntity<>(requestedUser, HttpStatus.OK);
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}


Again, that controller works fine and is able to receive POST requests as well as return user info in JSON format EXCEPT for when I have the
WebSecurityConfigurerAdapter
class (which I need to enable OAuth2.0 and CSRF protection later).

Answer

I'll add a little more documentation for posterity. As Jake said, the line

.formLogin().loginPage("/login").permitAll()

Was in fact the problem. According to the documentation there are several requirements for loginPage:

  • It must be an HTTP POST
  • It must be submitted to AbstractAuthenticationFilterConfigurer.loginProcessingUrl(String)
  • It should include the username as an HTTP parameter by the name of usernameParameter(String)
  • It should include the password as an HTTP parameter by the name of passwordParameter(String)

The method definition is missing the required http parameters that the loginPage() method requires.