银行项目开发过程当中,基本都会采用 spring 框架,因此彻底能够不用本身开发 filter 去拦截 csrf 攻击的请求,而直接采用实现 spring 提供的 HandlerInterceptor 来实现。 从本质上来讲,这也是一个 filter. 我这里就直接实现它来 防止 csrf 攻击.java
基本思路:
1. 用户登陆以后,后台程序生产一个 csrftoken 的 token ,放在 cookies 中,而且记录在 session 中。
2. 当客户端发出请求的访问后台程序的时候,通过本身实现的HandlerInterceptor 来拦截.
3. 拦截的基本方法是检查请求的参数中是否有csrftoken ,并检查这个值,是否合法有效(不为空,而且获得的参数等于cookies 中保存的值,并且还要等于session 中的值,那么就是合法的)web
package com.yihaomen.intercepter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class CsrfIntercepter implements HandlerInterceptor {
public static final String CSRFNUMBER = "csrftoken";
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
String keyFromRequestParam = (String) request.getParameter(CSRFNUMBER);
String keyFromCookies="";
boolean result=false;
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (int i = 0; i < cookies.length; i++) {
String name = cookies[i].getName();
if(CSRFNUMBER.equals(name) ) {
keyFromCookies= cookies[i].getValue();
}
}
}
if((keyFromRequestParam!=null && keyFromRequestParam.length()>0 &&
keyFromRequestParam.equals(keyFromCookies) &&
keyFromRequestParam.equals((String)request.getSession().getAttribute(CSRFNUMBER)))) {
result=true;
}else{
request.getRequestDispatcher("/error/400").forward(request, response);
}
return result;
}
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, Exception arg3) throws Exception {
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
}
}
spring