package org.fenixedu.bennu.spring.security; import java.security.SecureRandom; import java.util.Base64; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * Repository responsible for the handling of {@link CSRFToken}s. * * @author João Carvalho (joao.pedro.carvalho@tecnico.ulisboa.pt) * */ public class CSRFTokenRepository { private static final String CSRF_TOKEN_ATTRIBUTE = CSRFTokenRepository.class.getName() + ".CSRF_TOKEN"; private final SecureRandom random = new SecureRandom(); /** * Returns the {@link CSRFToken} associated with the given request. * * The default implementation stores the token itself in the {@link HttpSession}, generating a new one, if no token is * currently associated. * * @param request * The request for which to return the token * @return * The token associated with the given request */ public CSRFToken getToken(HttpServletRequest request) { HttpSession session = request.getSession(); CSRFToken token = (CSRFToken) session.getAttribute(CSRF_TOKEN_ATTRIBUTE); if (token == null) { synchronized (session) { token = (CSRFToken) session.getAttribute(CSRF_TOKEN_ATTRIBUTE); if (token == null) { token = generateNewToken(); session.setAttribute(CSRF_TOKEN_ATTRIBUTE, token); } } } return token; } /** * Generates a new {@link CSRFToken}. * * @return * A new, randomly-generated {@link CSRFToken} */ protected CSRFToken generateNewToken() { byte[] bytes = new byte[32]; random.nextBytes(bytes); return new CSRFToken(Base64.getUrlEncoder().encodeToString(bytes)); } }