001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019 package org.apache.shiro.mgt;
020
021 import org.apache.shiro.authz.AuthorizationException;
022 import org.apache.shiro.cache.CacheManagerAware;
023 import org.apache.shiro.session.Session;
024 import org.apache.shiro.session.SessionException;
025 import org.apache.shiro.session.mgt.DefaultSessionManager;
026 import org.apache.shiro.session.mgt.SessionContext;
027 import org.apache.shiro.session.mgt.SessionKey;
028 import org.apache.shiro.session.mgt.SessionManager;
029 import org.apache.shiro.util.LifecycleUtils;
030
031
032 /**
033 * Shiro support of a {@link SecurityManager} class hierarchy that delegates all
034 * {@link org.apache.shiro.session.Session session} operations to a wrapped
035 * {@link org.apache.shiro.session.mgt.SessionManager SessionManager} instance. That is, this class implements the
036 * methods in the {@link SessionManager SessionManager} interface, but in reality, those methods are merely
037 * passthrough calls to the underlying 'real' {@code SessionManager} instance.
038 * <p/>
039 * The remaining {@code SecurityManager} methods not implemented by this class or its parents are left to be
040 * implemented by subclasses.
041 * <p/>
042 * In keeping with the other classes in this hierarchy and Shiro's desire to minimize configuration whenever
043 * possible, suitable default instances for all dependencies will be created upon instantiation.
044 *
045 * @since 0.9
046 */
047 public abstract class SessionsSecurityManager extends AuthorizingSecurityManager {
048
049 /**
050 * The internal delegate <code>SessionManager</code> used by this security manager that manages all the
051 * application's {@link Session Session}s.
052 */
053 private SessionManager sessionManager;
054
055 /**
056 * Default no-arg constructor, internally creates a suitable default {@link SessionManager SessionManager} delegate
057 * instance.
058 */
059 public SessionsSecurityManager() {
060 super();
061 this.sessionManager = new DefaultSessionManager();
062 applyCacheManagerToSessionManager();
063 }
064
065 /**
066 * Sets the underlying delegate {@link SessionManager} instance that will be used to support this implementation's
067 * <tt>SessionManager</tt> method calls.
068 * <p/>
069 * This <tt>SecurityManager</tt> implementation does not provide logic to support the inherited
070 * <tt>SessionManager</tt> interface, but instead delegates these calls to an internal
071 * <tt>SessionManager</tt> instance.
072 * <p/>
073 * If a <tt>SessionManager</tt> instance is not set, a default one will be automatically created and
074 * initialized appropriately for the the existing runtime environment.
075 *
076 * @param sessionManager delegate instance to use to support this manager's <tt>SessionManager</tt> method calls.
077 */
078 public void setSessionManager(SessionManager sessionManager) {
079 this.sessionManager = sessionManager;
080 afterSessionManagerSet();
081 }
082
083 protected void afterSessionManagerSet() {
084 applyCacheManagerToSessionManager();
085 }
086
087 /**
088 * Returns this security manager's internal delegate {@link SessionManager SessionManager}.
089 *
090 * @return this security manager's internal delegate {@link SessionManager SessionManager}.
091 * @see #setSessionManager(org.apache.shiro.session.mgt.SessionManager) setSessionManager
092 */
093 public SessionManager getSessionManager() {
094 return this.sessionManager;
095 }
096
097 /**
098 * Calls {@link org.apache.shiro.mgt.AuthorizingSecurityManager#afterCacheManagerSet() super.afterCacheManagerSet()} and then immediately calls
099 * {@link #applyCacheManagerToSessionManager() applyCacheManagerToSessionManager()} to ensure the
100 * <code>CacheManager</code> is applied to the SessionManager as necessary.
101 */
102 protected void afterCacheManagerSet() {
103 super.afterCacheManagerSet();
104 applyCacheManagerToSessionManager();
105 }
106
107 /**
108 * Ensures the internal delegate <code>SessionManager</code> is injected with the newly set
109 * {@link #setCacheManager CacheManager} so it may use it for its internal caching needs.
110 * <p/>
111 * Note: This implementation only injects the CacheManager into the SessionManager if the SessionManager
112 * instance implements the {@link CacheManagerAware CacheManagerAware} interface.
113 */
114 protected void applyCacheManagerToSessionManager() {
115 if (this.sessionManager instanceof CacheManagerAware) {
116 ((CacheManagerAware) this.sessionManager).setCacheManager(getCacheManager());
117 }
118 }
119
120 public Session start(SessionContext context) throws AuthorizationException {
121 return this.sessionManager.start(context);
122 }
123
124 public Session getSession(SessionKey key) throws SessionException {
125 return this.sessionManager.getSession(key);
126 }
127
128 public void destroy() {
129 LifecycleUtils.destroy(getSessionManager());
130 this.sessionManager = null;
131 super.destroy();
132 }
133 }