spring security csrf 学习笔记
最近在学习和研究csrf攻击,项目中使用了spring security,提供了csrf防御的能力,本文对该功能的使用做记录和说明、总结。
已经有现成的springMVC项目,已经在web.xml设置好了filter,所有请求在分发到controller之前先被spring security处理。
项目中已经使用spring security完成关于登陆和用户认证、chookie、logout等功能,现在做的是开启csrf防御功能。
- 在
applicationContext-security.xml
配置文件中,将<csrf disabled="true"/>
修改为<csrf/>
,开启csrf防御功能。
登陆接口改造
登录页面不修改,点击登录时,请求会被spring security拦截,返回403错误,提示没有token,请求不会被后台servlet处理;
在登录的form上添加隐藏输入:
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
, 此时点击登录,则请求会被后台处理,提示用户名密码错误或者登录成功等。
注册接口改造
注册页面,使用ajax提交post请求,开启csrf防御后,若不修改,则ajax提交失败,返回403错误:
Failed to load resource: the server responded with a status of 403 (Forbidden)
在注册页面
register.jsp
的header
中添加:1
2
3
4<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>```
在`register.js`中添加代码:var ttoken = $(“meta[name=’_csrf’]”).attr(“content”);
var theader = $(“meta[name=’_csrf_header’]”).attr(“content”);
$(document).ajaxSend(function(e, xhr, options){
xhr.setRequestHeader(theader, ttoken);
});1
2
3
4
5
6
7
8
9
10
11
12
13此时再点击下一步,将不会返回403错误,而是返回后台处理请求后的结果。
如上,spring securtiy会拦截所有post请求,并校验token值,若没有token值或不正确,则返回403错误,后台不会处理请求。
### 退出登陆接口改造
必须要更正一下,之前我认为退出登录接口不是必须使用post方式,可以使用get方式,只是建议使用post方式:
> 同理,退出登陆接口也要从原本的get方式改为post方式,否则不会被spring security csrf处理。
>
> 官方文档的说法是,不想用post方式也可以,但是强烈建议用post方式...
从某种程度上来说也没错,因为确实可以通过额外的工作使得logout支持get方式,如下:@EnableWebSecurity
public class WebSecurityConfig extends
WebSecurityConfigurerAdapter {@Override
protected void configure(HttpSecurity http) throws Exception {
http
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher(“/logout”));
}
}
1 |
|
1 |
|
1 |
|
1 | 这样上传文件时就不会因为没有传token值而被拦截返回403错误,但是谁都可以上传临时文件到你服务器了。不过官网文档说鼓励这种做法因为临时文件的上传对大多数服务器没有严重影响? |
总结&参考
为了防止CSRF攻击,接口请求尽量使用post方式,开启spring security csrf后,能够防御大部分CSRF攻击。
参考链接: