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

Error 405 Request method 'POST' not supported Spring Security

我正在尝试实现一个具有 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} 在检查它们时都是空的。如果您需要任何其他信息,我会很高兴供应它。

登录页面没有权限?

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

您的表单操作指定

action="/login"

还有你的控制器

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

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

您可以尝试更改表单中的提交 url 或在 authorizeRequests() 方法中以某种方式指定接受来自 POST 的 /login。

所以,我想通了。我对问题中的代码做了以下更改:

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

希望对有类似需求的人有所帮助。

我知道这是一个 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}" />