fr.mycellar.interfaces.web.security.SecurityContextTokenRepository.java Source code

Java tutorial

Introduction

Here is the source code for fr.mycellar.interfaces.web.security.SecurityContextTokenRepository.java

Source

/*
 * 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();
            }
        }
    }
}