Java tutorial
/* * Copyright 2011, MyCellar * * This file is part of MyCellar. * * MyCellar is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * MyCellar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MyCellar. If not, see <http://www.gnu.org/licenses/>. */ package fr.mycellar.interfaces.web.security; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.joda.time.LocalDateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.token.KeyBasedPersistenceTokenService; import org.springframework.security.core.token.Token; import org.springframework.security.web.context.HttpRequestResponseHolder; import org.springframework.security.web.context.SecurityContextRepository; import fr.mycellar.configuration.SpringSecurityConfiguration; /** * @author speralta */ @Singleton @Named public class SecurityContextTokenRepository implements SecurityContextRepository { private static class TimedSecurityContext { private final SecurityContext securityContext; private LocalDateTime localDateTime; public TimedSecurityContext(SecurityContext securityContext, LocalDateTime localDateTime) { this.securityContext = securityContext; this.localDateTime = localDateTime; } } private static final Logger logger = LoggerFactory.getLogger(SecurityContextTokenRepository.class); private final Map<Token, TimedSecurityContext> securityContexts = new HashMap<>(); @Inject private KeyBasedPersistenceTokenService keyBasedPersistenceTokenService; @Override public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) { try { Object key = requestResponseHolder.getRequest() .getHeader(SpringSecurityConfiguration.TOKEN_HEADER_NAME); if ((key != null) && (key instanceof String)) { Token token = keyBasedPersistenceTokenService.verifyToken((String) key); if (token != null) { TimedSecurityContext context = securityContexts.get(token); if (context != null) { context.localDateTime = new LocalDateTime(); return context.securityContext; } } } } catch (Exception e) { // return SecurityContextHolder.createEmptyContext(); } return SecurityContextHolder.createEmptyContext(); } @Override public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) { Object key = response.getHeader(SpringSecurityConfiguration.TOKEN_HEADER_NAME); if ((key != null) && (key instanceof String)) { securityContexts.put(keyBasedPersistenceTokenService.verifyToken((String) key), new TimedSecurityContext(context, new LocalDateTime())); } } @Override public boolean containsContext(HttpServletRequest request) { try { Object key = request.getHeader(SpringSecurityConfiguration.TOKEN_HEADER_NAME); if ((key != null) && (key instanceof String)) { Token token = keyBasedPersistenceTokenService.verifyToken((String) key); if (token != null) { return securityContexts.containsKey(token); } } } catch (Exception e) { // return false; } return false; } public Token newToken(SecurityContext context) { Authentication auth = context.getAuthentication(); if ((auth != null) && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken)) { return keyBasedPersistenceTokenService.allocateToken(context.getAuthentication().getName()); } return null; } public void deleteToken(HttpServletRequest request) { securityContexts.remove(request.getHeader(SpringSecurityConfiguration.TOKEN_HEADER_NAME)); } @Scheduled(fixedRate = 60000) public void cleanRepository() { LocalDateTime expired = new LocalDateTime().minusMinutes(15); for (Iterator<Entry<Token, TimedSecurityContext>> iterator = securityContexts.entrySet() .iterator(); iterator.hasNext();) { Entry<Token, TimedSecurityContext> entry = iterator.next(); if (entry.getValue().localDateTime.isBefore(expired)) { logger.debug("Remove expired token: {}", entry.getKey().getKey()); iterator.remove(); } } } }