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

Posted

技术标签:

【中文标题】错误 405 请求方法 \'POST\' 不支持 Spring Security【英文标题】:Error 405 Request method 'POST' not supported Spring Security错误 405 请求方法 'POST' 不支持 Spring Security 【发布时间】:2016-06-16 12:30:18 【问题描述】:

我正在尝试使用 Spring 安全性实现一个简单的登录页面。无论我做什么,在提交表单输入时我总是会收到错误Error 405 Request method 'POST' not supported相关文件: 安全配置.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 在检查它们时都是空的。如果您需要任何其他信息,我很乐意提供。

【问题讨论】:

【参考方案1】:

我知道这是一个 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】:

所以,我想通了。我对问题中的代码进行了以下更改: 在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】:

您的表单操作指定

action="/login"

还有你的控制器

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

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

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

【讨论】:

您可以在控制器中使用相同的 URL,只要它不是RequestMethod.POST【参考方案4】:

登录页面没有权限?

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

【讨论】:

感谢您的宝贵时间,但这仍然会产生完全相同的错误:/ 我遇到了和你一样的问题,但也不确定解决了什么问题 :( 链接:***.com/questions/34080594/…

以上是关于错误 405 请求方法 'POST' 不支持 Spring Security的主要内容,如果未能解决你的问题,请参考以下文章

为啥来自 Vuejs 的 Laravel 8 的 AJAX POST 请求会引发 405(不支持的方法)错误?

HTTP状态405 - 不支持请求方法'POST' - Spring Security

HTTP 状态 405 - 不支持请求方法“POST”(Spring MVC)

不支持 Spring MVC 请求方法“POST”-> HTTP 405

Spring MVC HTTP 状态 405 - 不支持请求方法“POST”

Spring:状态 405。不支持请求方法“POST”