package jp.sourceforge.rabbitBTS.interceptors;
+import java.util.List;
+import java.util.Date;
+import java.util.LinkedList;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals("POST")
&& handler instanceof IController) {
- final String sentToken = request.getParameter("secureToken");
- final String sessionToken = (String) request.getSession()
- .getAttribute("secureToken");
final IController c = (IController) handler;
-
- if (StringUtils.equals(sentToken, sessionToken)) {
+ final CsrfChecker checker = new CsrfChecker(request);
+ if (checker.checkTokenValid()) {
c.setCsrfSafe(true);
} else {
c.setCsrfSafe(false);
Sht.log(this).warning("CSRF detected.");
}
-
}
return true;
}
// リダイレクトする場合は不要
if (mav != null) {
if (!StringUtils.startsWith(mav.getViewName(), "redirect:")) {
- final String token = RandomStringUtils.randomAlphanumeric(128);
- request.getSession().setAttribute("secureToken", token);
+ final CsrfChecker checker = new CsrfChecker(request);
+ final String token = checker.saveNewToken();
mav.addObject("secureToken", token);
}
}
}
}
+ class CsrfChecker{
+ private HttpServletRequest req;
+ private List<Object> tokenList;
+ public CsrfChecker(HttpServletRequest request){
+ this.req = request;
+ this.tokenList = (List)request.getSession().getAttribute("tokenList");
+ if(this.tokenList == null){
+ this.tokenList = new LinkedList<Object>();
+ request.getSession().setAttribute("tokenList", this.tokenList);
+ }
+ }
+
+ /**
+ * トークンをセッションに保存する。
+ * @return 保存された新規トークン
+ */
+ public String saveNewToken(){
+ final String token = RandomStringUtils.randomAlphanumeric(128);
+ this.tokenList.add(token);
+ this.tokenList.add(new Date());
+
+ return token;
+ }
+
+ public boolean checkTokenValid(){
+ final String reqToken = this.req.getParameter("secureToken");
+ boolean found = false;
+ for(int i = 0; i < tokenList.size(); i+=2){
+ final String token = (String)this.tokenList.get(i);
+ if(token.equals(reqToken)){
+ // TODO:期限チェック
+ found = true;
+ break;
+ }
+ }
+ // TODO:期限切れ削除
+ return found;
+ }
+ }
+
}