/** * A manager for the CSRF token for a given session. The {@link #getTokenForSession(HttpSession)} should used to obtain * the token value for the current session (and this should be the only way to obtain the token value). */ publicfinalclassCSRFTokenManager{
/** * The token parameter name */ staticfinal String CSRF_PARAM_NAME = "xToken";
/** * The location on the session which stores the token */ publicfinalstatic String CSRF_TOKEN_FOR_SESSION_ATTR_NAME = CSRFTokenManager.class.getName() + ".tokenval";
publicstatic String getTokenForSession(HttpSession session){ String token = null; // cannot allow more than one token on a session - in the case of two requests trying to // init the token concurrently synchronized (session) { token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME); if (null == token) { token = UUID.randomUUID().toString(); session.setAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME, token); } } return token; }
/** * Extracts the token value from the session * * @param request * @return */ publicstatic String getTokenFromRequest(HttpServletRequest request){ String token = request.getParameter(CSRF_PARAM_NAME); if (token == null || "".equals(token)) { token = request.getHeader(CSRF_PARAM_NAME); } return token; }
public class CSRFTool { public static String getToken(HttpServletRequest request) { return CSRFTokenManager.getTokenForSession(request.getSession()); } }
/** * A Spring MVC <code>HandlerInterceptor</code> which is responsible to enforce CSRF token validity on incoming posts * requests. The interceptor should be registered with Spring MVC servlet using the following syntax: * * <mvc:interceptors> * <bean class="com.javan.security.CSRFHandlerInterceptor"/> * </mvc:interceptors> * * @see CSRFRequestDataValueProcessor */ publicclassCSRFHandlerInterceptorextendsHandlerInterceptorAdapter{
if (handler instanceof DefaultServletHttpRequestHandler) { returntrue; }
if (request.getMethod().equalsIgnoreCase("GET")) { // GET - allow the request returntrue; } else { // This is a POST request - need to check the CSRF token String sessionToken = CSRFTokenManager.getTokenForSession(request.getSession()); String requestToken = CSRFTokenManager.getTokenFromRequest(request); if (sessionToken.equals(requestToken)) { returntrue; } else { response.sendError(HttpServletResponse.SC_FORBIDDEN, "Bad or missing CSRF value"); returnfalse; } } } }