错误405请求方法'POST'不支持Spring Security

时间:2016-03-03 09:16:30

标签: spring spring-mvc spring-security csrf-protection

我正在尝试使用Spring安全性实现一个简单的登录页面。无论我做什么,在提交表单输入时总是会出现错误Error 405 Request method 'POST' not supported

相关文件:

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
{

}

我的控制器的一部分:

@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>

我认为问题在于我的$(_ csrf.parameterName}和$ {_ csrf.token}在检查时都是空的。如果您需要任何其他信息,我很乐意提供它。

4 个答案:

答案 0 :(得分:0)

所以,我已经弄明白了。我在我的问题中对代码做了以下更改:

web.xml我必须添加:

<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();
}

希望它可以帮助有类似需求的人。

答案 1 :(得分:0)

我知道这是一个3岁的问题,但是我的回答可以帮助其他人。所以,我也有这种情况。而且我发现Spring CSRF不允许POST方法。所以我所做的就是禁用CSRF并手动发送CSRF令牌,如下所示:

@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().disable();
}

并在JSP文件中:

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

答案 2 :(得分:-1)

没有登录页面的许可?

.antMatchers("/login").permitAll()

我给你一些登录页面的例子:

http
    .authorizeRequests()
    .antMatchers("/login").permitAll()
    .antMatchers("/**").fullyAuthenticated()
    .and()
    .requiresChannel().anyRequest().requiresSecure().and()
    .formLogin().loginPage("/login").defaultSuccessUrl("/main", true)
    .failureUrl("/login.do?error")
    .usernameParameter("username").passwordParameter("password")

答案 3 :(得分:-1)

您的表单操作指定

action="/login"

和你的控制器

@RequestMapping(value = "/login", method = RequestMethod.GET)

我的猜测是你的表单提交与控制器方法匹配,这就是你得到异常的原因。

您可以尝试在表单中更改提交URL,或者在authorizeRequests()方法中以某种方式指定接受/从POST登录。