/* * Copyright (c) 2013, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.identity.application.authentication.framework.cache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.identity.application.authentication.framework.store.SessionContextDO; import org.wso2.carbon.identity.application.authentication.framework.store.SessionDataStore; import org.wso2.carbon.identity.application.common.cache.BaseCache; import org.wso2.carbon.idp.mgt.util.IdPManagementUtil; import java.util.concurrent.TimeUnit; public class SessionContextCache extends BaseCache<SessionContextCacheKey, SessionContextCacheEntry> { private static final String SESSION_CONTEXT_CACHE_NAME = "AppAuthFrameworkSessionContextCache"; private static final Log log = LogFactory.getLog(SessionContextCache.class); private static volatile SessionContextCache instance; private SessionContextCache() { super(SESSION_CONTEXT_CACHE_NAME); } public static SessionContextCache getInstance() { if (instance == null) { synchronized (SessionContextCache.class) { if (instance == null) { instance = new SessionContextCache(); } } } return instance; } public void addToCache(SessionContextCacheKey key, SessionContextCacheEntry entry) { entry.setAccessedTime(); super.addToCache(key, entry); SessionDataStore.getInstance().storeSessionData(key.getContextId(), SESSION_CONTEXT_CACHE_NAME, entry); } public SessionContextCacheEntry getValueFromCache(SessionContextCacheKey key) { SessionContextCacheEntry cacheEntry = super.getValueFromCache(key); // Retrieve session from the database if its not in cache if (cacheEntry == null) { SessionContextDO sessionContextDO = SessionDataStore.getInstance(). getSessionContextData(key.getContextId(), SESSION_CONTEXT_CACHE_NAME); if (sessionContextDO != null) { cacheEntry = new SessionContextCacheEntry(sessionContextDO); } } if (cacheEntry == null) { if(log.isDebugEnabled()) { log.debug("Session corresponding to the key : " + key.getContextId() + " cannot be found."); } return null; } else if (isValidIdleSession(key, cacheEntry) || isValidRememberMeSession(key, cacheEntry)) { if(log.isDebugEnabled()) { log.debug("Found a valid session corresponding to the key : " + key.getContextId()); } return cacheEntry; } else { if(log.isDebugEnabled()) { log.debug("Found an expired session corresponding to the key : " + key.getContextId()); } clearCacheEntry(key); return null; } } public void clearCacheEntry(SessionContextCacheKey key) { super.clearCacheEntry(key); SessionDataStore.getInstance().clearSessionData(key.getContextId(), SESSION_CONTEXT_CACHE_NAME); } /** * Check whether the given session context is valid according to idle session timeout restrictions. * * @param key SessionContextCacheKey * @param cacheEntry SessionContextCacheEntry * @return true if the session context is valid as per idle session configs; false otherwise */ private boolean isValidIdleSession(SessionContextCacheKey key, SessionContextCacheEntry cacheEntry) { String contextId = key.getContextId(); if (cacheEntry == null) { return false; } String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); long idleSessionTimeOut = TimeUnit.SECONDS.toMillis(IdPManagementUtil.getIdleSessionTimeOut(tenantDomain)); long currentTime = System.currentTimeMillis(); long lastAccessedTime = cacheEntry.getAccessedTime(); if (log.isDebugEnabled()) { log.debug("Context ID : " + contextId + " :: idleSessionTimeOut : " + idleSessionTimeOut + ", currentTime : " + currentTime + ", lastAccessedTime : " + lastAccessedTime); } if (currentTime - lastAccessedTime > idleSessionTimeOut) { if (log.isDebugEnabled()) { log.debug("Context ID : " + contextId + " :: Idle session expiry"); } return false; } return true; } /** * Check whether the given session context is valid according to remember me session timeout restrictions. * * @param key SessionContextCacheKey * @param cacheEntry SessionContextCacheEntry * @return true if the session context is valid as per remember me session configs; false otherwise */ private boolean isValidRememberMeSession(SessionContextCacheKey key, SessionContextCacheEntry cacheEntry) { String contextId = key.getContextId(); if (cacheEntry == null) { return false; } if (!cacheEntry.getContext().isRememberMe()) { return false; } String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); long rememberMeSessionTimeOut = TimeUnit.SECONDS.toMillis(IdPManagementUtil.getRememberMeTimeout(tenantDomain)); long currentTime = System.currentTimeMillis(); long lastAccessedTime = cacheEntry.getAccessedTime(); if (log.isDebugEnabled()) { log.debug("Context ID : " + contextId + " :: rememberMeSessionTimeOut : " + rememberMeSessionTimeOut + ", currentTime : " + currentTime + ", lastAccessedTime : " + lastAccessedTime); } if (currentTime - lastAccessedTime > rememberMeSessionTimeOut) { if (log.isDebugEnabled()) { log.debug("Context ID : " + contextId + " :: Remember me session expiry"); } return false; } return true; } }