配置Spring Security 3.2后,_csrf.token
未绑定到请求或会话对象。
这是spring security配置:
<http pattern="/login.jsp" security="none"/>
<http>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=1"
default-target-url="/index.jsp"/>
<logout/>
<csrf />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="test" password="test" authorities="ROLE_USER/>
</user-service>
</authentication-provider>
</authentication-manager>
login.jsp文件
<form name="f" action="${contextPath}/j_spring_security_check" method="post" >
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<button id="ingresarButton"
name="submit"
type="submit"
class="right"
style="margin-right: 10px;">Ingresar</button>
<span>
<label for="usuario">Usuario :</label>
<input type="text" name="j_username" id="u" class="" value=''/>
</span>
<span>
<label for="clave">Contraseña :</label>
<input type="password"
name="j_password"
id="p"
class=""
onfocus="vc_psfocus = 1;"
value="">
</span>
</form>
它呈现下一个html:
<input type="hidden" name="" value="" />
结果是403 HTTP状态:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
更新 在一些调试之后,请求对象从DelegatingFilterProxy中获得良好的形式,但是在CoyoteAdapter的第469行中它执行request.recycle();这抹去了所有属性......
我使用JDK 1.7在Tomcat 6.0.36,7.0.50中进行测试。
我还没有理解这种行为,而不是,如果有人指出我使用与CSRF一起使用的Spring Security 3.2的应用程序示例战争的方向,那么就有可能。
答案 0 :(得分:91)
看起来您的Spring应用程序中的CSRF(跨站点请求伪造)保护已启用。实际上它是默认启用的。
根据spring.io:
什么时候应该使用CSRF保护?我们的建议是使用CSRF 保护浏览器可以处理的任何请求 普通用户。如果您只是创建使用的服务 非浏览器客户端,您可能希望禁用CSRF保护。
所以要禁用它:
@Configuration
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
如果您希望启用CSRF保护,则必须在表单中加入csrftoken
。你可以这样做:
<form .... >
....other fields here....
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
您甚至可以在表单的操作中包含CSRF令牌:
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">
答案 1 :(得分:28)
您是否应该添加到登录表单?;
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
如Spring安全文档中的here所述
答案 2 :(得分:12)
如果您将申请安全=&#34;无&#34;那么就不会生成csrf令牌。页面不会通过安全筛选器。使用角色ANONYMOUS。
我没有详细介绍,但它对我有用。
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login.jsp" access="hasRole('ANONYMOUS')" />
<!-- you configuration -->
</http>
答案 3 :(得分:7)
尝试将此更改为<csrf />
:<csrf disabled="true"/>
。它应该禁用csfr。
答案 4 :(得分:6)
有了百里香,你可以补充一下:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
答案 5 :(得分:6)
用于禁用csrf的Spring文档:https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-configure
@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}
答案 6 :(得分:4)
我曾经遇到同样的问题。
您的配置使用security =“none”,因此无法生成_csrf:
<http pattern="/login.jsp" security="none"/>
你可以为page /login.jsp设置access =“IS_AUTHENTICATED_ANONYMOUSLY”替换上面的配置:
<http>
<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp"
authentication-failure-url="/login.jsp?error=1"
default-target-url="/index.jsp"/>
<logout/>
<csrf />
</http>
答案 7 :(得分:2)
我认为csrf仅适用于弹簧形式
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
更改为form:form
代码并查看其有效。
答案 8 :(得分:1)
请参阅我的工作示例应用on Github并与您的设置进行比较。
答案 9 :(得分:1)
其中一个解决方案都不适用于我。 Spring中唯一能为我工作的是:
行动= “./上传?的 $ {_ csrf.parameterName} 强> = $ {_ csrf.token}”
替换为:
行动= “./上传?的 _csrf 强> = $ {_ csrf.token}”
(Spring 5,在java配置中启用了csrf)
答案 10 :(得分:0)
在您的控制器中添加以下内容:
@RequestParam(value = "_csrf", required = false) String csrf
在jsp页面上添加
<form:form modelAttribute="someName" action="someURI?${_csrf.parameterName}=${_csrf.token}
答案 11 :(得分:-1)
我使用Spring 4.2.3版本jar来保证弹簧安全,但是我得到了同样的错误。然后我降级到3.1.4,这完美无缺。
以下是我对pom.xml的依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.5.4-Final</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.1.Final</version>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>