private void rotateTokens(HttpServletRequest request) {
    HttpSession session = request.getSession(true);

    /** rotate master token * */
    String tokenFromSession = null;

    try {
      tokenFromSession = RandomGenerator.generateRandomId(getPrng(), getTokenLength());
    } catch (Exception e) {
      throw new RuntimeException(
          String.format("unable to generate the random token - %s", e.getLocalizedMessage()), e);
    }

    session.setAttribute(getSessionKey(), tokenFromSession);

    /** rotate page token * */
    if (isTokenPerPageEnabled()) {
      @SuppressWarnings("unchecked")
      Map<String, String> pageTokens =
          (Map<String, String>) session.getAttribute(CsrfGuard.PAGE_TOKENS_KEY);

      try {
        pageTokens.put(
            request.getRequestURI(), RandomGenerator.generateRandomId(getPrng(), getTokenLength()));
      } catch (Exception e) {
        throw new RuntimeException(
            String.format("unable to generate the random token - %s", e.getLocalizedMessage()), e);
      }
    }
  }
  public void updateTokens(HttpServletRequest request) {
    /** cannot create sessions if response already committed * */
    HttpSession session = request.getSession(false);

    if (session != null) {
      /** create master token if it does not exist * */
      updateToken(session);

      /** create page specific token * */
      if (isTokenPerPageEnabled()) {
        @SuppressWarnings("unchecked")
        Map<String, String> pageTokens =
            (Map<String, String>) session.getAttribute(CsrfGuard.PAGE_TOKENS_KEY);

        /** first time initialization * */
        if (pageTokens == null) {
          pageTokens = new HashMap<String, String>();
          session.setAttribute(CsrfGuard.PAGE_TOKENS_KEY, pageTokens);
        }

        /** create token if it does not exist * */
        if (isProtectedPageAndMethod(request)) {
          createPageToken(pageTokens, request.getRequestURI());
        }
      }
    }
  }
  public String getTokenValue(HttpServletRequest request, String uri) {
    String tokenValue = null;
    HttpSession session = request.getSession(false);

    if (session != null) {
      if (isTokenPerPageEnabled()) {
        @SuppressWarnings("unchecked")
        Map<String, String> pageTokens =
            (Map<String, String>) session.getAttribute(CsrfGuard.PAGE_TOKENS_KEY);

        if (pageTokens != null) {
          if (isTokenPerPagePrecreate()) {
            createPageToken(pageTokens, uri);
          }
          tokenValue = pageTokens.get(uri);
        }
      }

      if (tokenValue == null) {
        tokenValue = (String) session.getAttribute(getSessionKey());
      }
    }

    return tokenValue;
  }
  private void verifySessionToken(HttpServletRequest request) throws CsrfGuardException {
    HttpSession session = request.getSession(true);
    String tokenFromSession = (String) session.getAttribute(getSessionKey());
    String tokenFromRequest = request.getParameter(getTokenName());

    if (tokenFromRequest == null) {
      /** FAIL: token is missing from the request * */
      throw new CsrfGuardException("required token is missing from the request");
    } else if (!tokenFromSession.equals(tokenFromRequest)) {
      /** FAIL: the request token does not match the session token * */
      throw new CsrfGuardException("request token does not match session token");
    }
  }
  public boolean isValidRequest(HttpServletRequest request, HttpServletResponse response) {
    boolean valid = !isProtectedPageAndMethod(request);
    HttpSession session = request.getSession(true);
    String tokenFromSession = (String) session.getAttribute(getSessionKey());

    /** sending request to protected resource - verify token * */
    if (tokenFromSession != null && !valid) {
      try {
        if (isAjaxEnabled() && isAjaxRequest(request)) {
          verifyAjaxToken(request);
        } else if (isTokenPerPageEnabled()) {
          verifyPageToken(request);
        } else {
          verifySessionToken(request);
        }
        valid = true;
      } catch (CsrfGuardException csrfe) {
        for (IAction action : getActions()) {
          try {
            action.execute(request, response, csrfe, this);
          } catch (CsrfGuardException exception) {
            getLogger().log(LogLevel.Error, exception);
          }
        }
      }

      /** rotate session and page tokens * */
      if (!isAjaxRequest(request) && isRotateEnabled()) {
        rotateTokens(request);
      }
      /** expected token in session - bad state * */
    } else if ((tokenFromSession == null) && !valid) {
      throw new IllegalStateException(
          "CsrfGuard expects the token to exist in session at this point");
    } else {
      /** unprotected page - nothing to do * */
    }

    return valid;
  }
  private void verifyPageToken(HttpServletRequest request) throws CsrfGuardException {
    HttpSession session = request.getSession(true);
    @SuppressWarnings("unchecked")
    Map<String, String> pageTokens =
        (Map<String, String>) session.getAttribute(CsrfGuard.PAGE_TOKENS_KEY);

    String tokenFromPages = (pageTokens != null ? pageTokens.get(request.getRequestURI()) : null);
    String tokenFromSession = (String) session.getAttribute(getSessionKey());
    String tokenFromRequest = request.getParameter(getTokenName());

    if (tokenFromRequest == null) {
      /** FAIL: token is missing from the request * */
      throw new CsrfGuardException("required token is missing from the request");
    } else if (tokenFromPages != null) {
      if (!tokenFromPages.equals(tokenFromRequest)) {
        /** FAIL: request does not match page token * */
        throw new CsrfGuardException("request token does not match page token");
      }
    } else if (!tokenFromSession.equals(tokenFromRequest)) {
      /** FAIL: the request token does not match the session token * */
      throw new CsrfGuardException("request token does not match session token");
    }
  }