Search code examples
springspring-mvcspring-securitycsrf-protection

Error 405 Request method 'POST' not supported Spring Security


I am trying to implement a simple login page with Spring security. Whatever I do, I always get an error Error 405 Request method 'POST' not supported when submitting form input.

Related files:

SecurityConfig.java:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.inMemoryAuthentication().withUser("admin").password("abc123").roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {

        http.authorizeRequests()
                .antMatchers("/", "/thank-you", "/faq", "/legal", "/policy").permitAll()
                .antMatchers("/admin/**").access("hasRole('ADMIN')")
                .and().formLogin().loginPage("/login")
                .usernameParameter("ssoId").passwordParameter("password")
                .and().csrf()
                .and().exceptionHandling().accessDeniedPage("/");
    }
}

SecurityWebApplicationInitializer.java:

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
{

}

part of my controller:

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView loginPage(  )
{
    return new ModelAndView("WEB-INF/views/login");
}

pom.xml:

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>4.0.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>4.0.4.RELEASE</version>
</dependency>

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>4.0.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.2.5.RELEASE</version>
</dependency>

login.jsp:

<form action="/login" method="post">
<div>
  <label for="j_username">Username</label> <br>
  <input type="text" class="form-control" id="j_username" name="ssoId" required />
</div>
<div>
  <label for="j_password">Password</label> <br>
    <input type="password" class="form-control" id="j_password" name="password" required />
</div>

<input type="hidden" name="${_csrf.parameterName}"   value="${_csrf.token}" />

<div class="form-actions">
  <input type="submit" value="Log in" />
</div>

I think the problem is with the fact that my $(_csrf.parameterName} and ${_csrf.token} are both empty when Inspecting them. If you need any additional information, I would be happy to supply it.


Solution

  • So, I have figured it out. I did the following changes to the code in my question:

    In web.xml I had to add:

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    login.jsp:

    <form name='loginForm' action="/login" method='POST'>
    <div>
      <label for="username">Username</label> <br>
      <input type="text" class="form-control" id="username" name="username" required />
    </div>
    <div>
      <label for="password">Password</label> <br>
        <input type="password" class="form-control" id="password" name="password" required />
    </div>
    
    <input type="hidden" name="${_csrf.parameterName}"   value="${_csrf.token}" />
    
    <div class="form-actions">
      <input type="submit" value="Log in" />
    </div>
    

    SecurityConfig.java:

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .antMatchers("/", "/login").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .and()
                .formLogin().loginPage("/login")
                .defaultSuccessUrl("/admin").failureUrl("/login")
                .and()
                .csrf();
    }
    

    Hope it helps someone in a similar need.