配置Spring Security 3.2之后,_csrf.token
未绑定(bind)到请求或 session 对象。
这是spring安全配置:
<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进行一些应用程序示例 war 的方向是可能的。
最佳答案
看起来您的Spring应用程序中的CSRF(跨站点请求伪造)保护已启用。实际上,默认情况下它是启用的。
根据spring.io:
所以要禁用它:
@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 token :
<form action="./upload?${_csrf.parameterName}=${_csrf.token}" method="post" enctype="multipart/form-data">