All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.shiro.session.mgt.AbstractValidatingSessionManager Maven / Gradle / Ivy

There is a newer version: 3.9
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.shiro.session.mgt;

import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.session.ExpiredSessionException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.util.Destroyable;
import org.apache.shiro.util.LifecycleUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;


/**
 * Default business-tier implementation of the {@link ValidatingSessionManager} interface.
 *
 * @since 0.1
 */
public abstract class AbstractValidatingSessionManager extends AbstractNativeSessionManager
        implements ValidatingSessionManager, Destroyable {

    //TODO - complete JavaDoc

    private static final Logger log = LoggerFactory.getLogger(AbstractValidatingSessionManager.class);

    /**
     * The default interval at which sessions will be validated (1 hour);
     * This can be overridden by calling {@link #setSessionValidationInterval(long)}
     */
    public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = MILLIS_PER_HOUR;

    protected boolean sessionValidationSchedulerEnabled;

    /**
     * Scheduler used to validate sessions on a regular basis.
     */
    protected SessionValidationScheduler sessionValidationScheduler;

    protected long sessionValidationInterval;

    public AbstractValidatingSessionManager() {
        this.sessionValidationSchedulerEnabled = true;
        this.sessionValidationInterval = DEFAULT_SESSION_VALIDATION_INTERVAL;
    }

    public boolean isSessionValidationSchedulerEnabled() {
        return sessionValidationSchedulerEnabled;
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public void setSessionValidationSchedulerEnabled(boolean sessionValidationSchedulerEnabled) {
        this.sessionValidationSchedulerEnabled = sessionValidationSchedulerEnabled;
    }

    public void setSessionValidationScheduler(SessionValidationScheduler sessionValidationScheduler) {
        this.sessionValidationScheduler = sessionValidationScheduler;
    }

    public SessionValidationScheduler getSessionValidationScheduler() {
        return sessionValidationScheduler;
    }

    private void enableSessionValidationIfNecessary() {
        SessionValidationScheduler scheduler = getSessionValidationScheduler();
        if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) {
            enableSessionValidation();
        }
    }

    /**
     * If using the underlying default SessionValidationScheduler (that is, the
     * {@link #setSessionValidationScheduler(SessionValidationScheduler) setSessionValidationScheduler} method is
     * never called) , this method allows one to specify how
     * frequently session should be validated (to check for orphans).  The default value is
     * {@link #DEFAULT_SESSION_VALIDATION_INTERVAL}.
     * 

* If you override the default scheduler, it is assumed that overriding instance 'knows' how often to * validate sessions, and this attribute will be ignored. *

* Unless this method is called, the default value is {@link #DEFAULT_SESSION_VALIDATION_INTERVAL}. * * @param sessionValidationInterval the time in milliseconds between checking for valid sessions to reap orphans. */ public void setSessionValidationInterval(long sessionValidationInterval) { this.sessionValidationInterval = sessionValidationInterval; } public long getSessionValidationInterval() { return sessionValidationInterval; } @Override protected final Session doGetSession(final SessionKey key) throws InvalidSessionException { enableSessionValidationIfNecessary(); log.trace("Attempting to retrieve session with key {}", key); Session s = retrieveSession(key); if (s != null) { validate(s, key); } return s; } /** * Looks up a session from the underlying data store based on the specified session key. * * @param key the session key to use to look up the target session. * @return the session identified by {@code sessionId}. * @throws UnknownSessionException if there is no session identified by {@code sessionId}. */ protected abstract Session retrieveSession(SessionKey key) throws UnknownSessionException; protected Session createSession(SessionContext context) throws AuthorizationException { enableSessionValidationIfNecessary(); return doCreateSession(context); } protected abstract Session doCreateSession(SessionContext initData) throws AuthorizationException; protected void validate(Session session, SessionKey key) throws InvalidSessionException { try { doValidate(session); } catch (ExpiredSessionException ese) { onExpiration(session, ese, key); throw ese; } catch (InvalidSessionException ise) { onInvalidation(session, ise, key); throw ise; } } protected void onExpiration(Session s, ExpiredSessionException ese, SessionKey key) { log.trace("Session with id [{}] has expired.", s.getId()); onExpiration(s); notifyExpiration(s); afterExpired(s); } protected void onExpiration(Session session) { onChange(session); } protected void afterExpired(Session session) { } protected void onInvalidation(Session s, InvalidSessionException ise, SessionKey key) { if (ise instanceof ExpiredSessionException) { onExpiration(s, (ExpiredSessionException) ise, key); return; } log.trace("Session with id [{}] is invalid.", s.getId()); onStop(s); notifyStop(s); afterStopped(s); } protected void doValidate(Session session) throws InvalidSessionException { if (session instanceof ValidatingSession) { ((ValidatingSession) session).validate(); } else { String msg = "The " + getClass().getName() + " implementation only supports validating " + "Session implementations of the " + ValidatingSession.class.getName() + " interface. " + "Please either implement this interface in your session implementation or override the " + AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation."; throw new IllegalStateException(msg); } } /** * Subclass template hook in case per-session timeout is not based on * {@link org.apache.shiro.session.Session#getTimeout()}. *

*

This implementation merely returns {@link org.apache.shiro.session.Session#getTimeout()}

* * @param session the session for which to determine session timeout. * @return the time in milliseconds the specified session may remain idle before expiring. */ protected long getTimeout(Session session) { return session.getTimeout(); } protected SessionValidationScheduler createSessionValidationScheduler() { ExecutorServiceSessionValidationScheduler scheduler; if (log.isDebugEnabled()) { log.debug("No sessionValidationScheduler set. Attempting to create default instance."); } scheduler = new ExecutorServiceSessionValidationScheduler(this); scheduler.setInterval(getSessionValidationInterval()); if (log.isTraceEnabled()) { log.trace("Created default SessionValidationScheduler instance of type [" + scheduler.getClass().getName() + "]."); } return scheduler; } protected void enableSessionValidation() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler == null) { scheduler = createSessionValidationScheduler(); setSessionValidationScheduler(scheduler); } if (log.isInfoEnabled()) { log.info("Enabling session validation scheduler..."); } scheduler.enableSessionValidation(); afterSessionValidationEnabled(); } protected void afterSessionValidationEnabled() { } protected void disableSessionValidation() { beforeSessionValidationDisabled(); SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler != null) { try { scheduler.disableSessionValidation(); if (log.isInfoEnabled()) { log.info("Disabled session validation scheduler."); } } catch (Exception e) { if (log.isDebugEnabled()) { String msg = "Unable to disable SessionValidationScheduler. Ignoring (shutting down)..."; log.debug(msg, e); } } LifecycleUtils.destroy(scheduler); setSessionValidationScheduler(null); } } protected void beforeSessionValidationDisabled() { } public void destroy() { disableSessionValidation(); } /** * @see ValidatingSessionManager#validateSessions() */ public void validateSessions() { if (log.isInfoEnabled()) { log.info("Validating all active sessions..."); } int invalidCount = 0; Collection activeSessions = getActiveSessions(); if (activeSessions != null && !activeSessions.isEmpty()) { for (Session s : activeSessions) { try { //simulate a lookup key to satisfy the method signature. //this could probably stand to be cleaned up in future versions: SessionKey key = new DefaultSessionKey(s.getId()); validate(s, key); } catch (InvalidSessionException e) { if (log.isDebugEnabled()) { boolean expired = (e instanceof ExpiredSessionException); String msg = "Invalidated session with id [" + s.getId() + "]" + (expired ? " (expired)" : " (stopped)"); log.debug(msg); } invalidCount++; } } } if (log.isInfoEnabled()) { String msg = "Finished session validation."; if (invalidCount > 0) { msg += " [" + invalidCount + "] sessions were stopped."; } else { msg += " No sessions were stopped."; } log.info(msg); } } protected abstract Collection getActiveSessions(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy