Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc 未找到预期的CSRF令牌。错误403_Spring Mvc_Spring Security_Csrf - Fatal编程技术网

Spring mvc 未找到预期的CSRF令牌。错误403

Spring mvc 未找到预期的CSRF令牌。错误403,spring-mvc,spring-security,csrf,Spring Mvc,Spring Security,Csrf,我有一个使用SpringSecurity3.2的SpringWeb应用程序。最初,我是根据内存中的凭据对用户进行身份验证。我的安全配置文件是: import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSe

我有一个使用SpringSecurity3.2的SpringWeb应用程序。最初,我是根据内存中的凭据对用户进行身份验证。我的安全配置文件是:

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .formLogin()
        .loginPage("/login")
      .and()
        .logout()
          .logoutSuccessUrl("/")
      .and()
      .rememberMe()
        .tokenRepository(new InMemoryTokenRepositoryImpl())
        .tokenValiditySeconds(2419200)
        .key("spittrKey")
      .and()
       .httpBasic()
         .realmName("Spittr")
      .and()
      .authorizeRequests()
        .antMatchers("/admin").authenticated()
        .antMatchers("spitter/me").authenticated()
        .antMatchers(HttpMethod.POST, "/spittles").authenticated()
        .anyRequest().permitAll();
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
    .inMemoryAuthentication()
        .withUser("admin").password("secman").roles("ADMIN").and()
        .withUser("mike").password("secman").roles("USER");
  }

}
我的应用程序的一部分有一个创建新帐户的页面:

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>Spitter</title>
    <link rel="stylesheet" type="text/css" 
      th:href="@{/resources/styles.css}"></link>
  </head>
  <body>
    <div id="header" th:include="page :: header"></div>

    <div id="content">
      <h1>Register</h1>

      <form method="POST" th:object="${spitter}">
        <div class="errors" th:if="${#fields.hasErrors('*')}">
             <h3 color="red">Please fix the following errors:</h3>
          <ul class="errsul">
            <li th:each="err : ${#fields.errors('*')}" 
                th:text="${err}">Input is incorrect</li>
          </ul>
        </div>

        <label th:class="${#fields.hasErrors('firstName')}? 'error'">First Name</label>:
          <input type="text" th:field="*{firstName}"  
             th:class="${#fields.hasErrors('firstName')}? 'error'" /><br/>             

        <label th:class="${#fields.hasErrors('lastName')}? 'error'">Last Name</label>:
          <input type="text" th:field="*{lastName}"
             th:class="${#fields.hasErrors('lastName')}? 'error'" /><br/>

        <label th:class="${#fields.hasErrors('email')}? 'error'">Email</label>:
          <input type="text" th:field="*{email}"
             th:class="${#fields.hasErrors('email')}? 'error'" /><br/>

        <label th:class="${#fields.hasErrors('username')}? 'error'">Username</label>:
          <input type="text" th:field="*{username}"
             th:class="${#fields.hasErrors('username')}? 'error'" /><br/>

        <label th:class="${#fields.hasErrors('password')}? 'error'">Password</label>:
          <input type="password" th:field="*{password}"  
             th:class="${#fields.hasErrors('password')}? 'error'" /><br/>

        <label>Confirm Password</label>:
          <input type="password" th:field="*{confirmPassword}" /><br/>

        <input type="submit" value="Register" />

      </form>
    </div>
    <div id="footer" th:include="page :: copy"></div>
  </body>
</html>
当然,我还将数据源作为SecurityConfig.java中的私有属性进行自动连接。当我改为基于jdbc的身份验证时,在提交表单注册新帐户时,我突然开始出现CSRF null异常。根据关于这个问题的其他stackoverflow帖子,我必须在我的注册表中添加以下内容:

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

这就解决了问题。我知道使用spring标记库会自动为您执行上述操作,使用

<form method="POST" th:action="@{/....}"/> 


在你的表格上,但我都没有用。我的表单提交URL由GET请求中用于显示表单的URL暗示。所以我的问题是,我所做的唯一改变是从内存中的身份验证转向基于jdbc的身份验证。我所做的唯一更改是上面对SecurityConfig.java的更改。在这样做的过程中,CSRF滤波似乎从非活动变为活动。这听起来对吗?我在Spring安全文档页面上找不到任何提示。

奇怪的是,从内存身份验证更改为jdbc身份验证将激活CSRF。那么您想禁用它吗?不,我不想禁用它,我知道怎么做。我只是想弄明白发生了什么。我认为在使用Java配置时,CSRF在Security2.3中默认处于活动状态。这似乎表明出于某种原因它不是活动的,至少在我转到jdbc身份验证之前是这样。我想不出我做的任何其他改变会影响CSRF。
<form method="POST" th:action="@{/....}"/>