一、保护的过程
防御csrf的过程大致如下
1. 给页面表单/接口添加token
1 | public String doAction(Map context, CGI cgi) { |
2. 在csrfFilter中检测token
1 |
|
二、实现相关类
为了防御csrf攻击我们需要一个过滤器来对请求进行合法性检测,检测的标准是验证一个token,这个token由CsrfTokenRespository接口的实现类来生产和管理token
1. 实现CsrfFilter
参考org.springframework.security.web.csrf.CsrfFilter
1 | public class CsrfFilter extends OncePerRequestFilter { |
2. 实现CsrfTokenRepository
改写org.springframework.security.web.csrf.CsrfTokenRepository
主要需要结合自己生产环境的模板引擎产出token
1 | public class HttpSessionCsrfTokenRepository implements CsrfTokenRepository { |
三、配置
我们编写的CsrfFilter如果是一个bean,那么实际上我们不能按普通的过滤器那样直接加入到容器中,而应该把它加入到spring-security的filterChain中,并且使用org.springframework.web.filter.DelegatingFilterProxy这个spring为我们提供的代理过滤器来将spring-security的filterChain嫁接到web容器的filterChain当中。
1. 添加依赖jar包
导入 spring-security-web 及 spring-security-config 两个jar包依赖
2. 配置web.xml
1 | <!--配置DelegatingFilterProxy来代理spring-security的filterChain--> |
3. 新增配置spring-security.xml
1 | <beans:beans xmlns="http://www.springframework.org/schema/security" |
四、抛弃spreing-security过重的filterChain
spring-security的filterChain中有很多filter,可以做很丰富的事情,一旦你使用了它,那么这些filter将都会被按顺序执行。如果你仅仅需要csrf防御,那么使用spring-security的filterChain对项目来说就太重了。我们可以如下使用自定义的原生filter来达到同样的目的。
1. 使用原生Filter
1 | <filter> |
2. 由web容器初始化CsrfFilter
1 | public class CsrfFilter implements Filter { |
参考文档
(EOF)杨威发布日期 :2017-01-20自由转载-非商用-非衍生-保持署名(知识共享3.0许可证)