Jake Miller
Jake Miller

Reputation: 2652

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).

Upvotes: 1

Views: 844

Answers (2)

John K
John K

Reputation: 462

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.

Upvotes: 2

Jake Miller
Jake Miller

Reputation: 2652

I fixed it.

This line was causing an error...

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

Removed it and now everything is working fine.

Upvotes: 0

Related Questions