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 * @author Les Hazlewood
046 * @since 0.9
047 */
048 public abstract class SessionsSecurityManager extends AuthorizingSecurityManager {
049
050 /**
051 * The internal delegate <code>SessionManager</code> used by this security manager that manages all the
052 * application's {@link Session Session}s.
053 */
054 private SessionManager sessionManager;
055
056 /**
057 * Default no-arg constructor, internally creates a suitable default {@link SessionManager SessionManager} delegate
058 * instance.
059 */
060 public SessionsSecurityManager() {
061 super();
062 this.sessionManager = new DefaultSessionManager();
063 applyCacheManagerToSessionManager();
064 }
065
066 /**
067 * Sets the underlying delegate {@link SessionManager} instance that will be used to support this implementation's
068 * <tt>SessionManager</tt> method calls.
069 * <p/>
070 * This <tt>SecurityManager</tt> implementation does not provide logic to support the inherited
071 * <tt>SessionManager</tt> interface, but instead delegates these calls to an internal
072 * <tt>SessionManager</tt> instance.
073 * <p/>
074 * If a <tt>SessionManager</tt> instance is not set, a default one will be automatically created and
075 * initialized appropriately for the the existing runtime environment.
076 *
077 * @param sessionManager delegate instance to use to support this manager's <tt>SessionManager</tt> method calls.
078 */
079 public void setSessionManager(SessionManager sessionManager) {
080 this.sessionManager = sessionManager;
081 afterSessionManagerSet();
082 }
083
084 protected void afterSessionManagerSet() {
085 applyCacheManagerToSessionManager();
086 }
087
088 /**
089 * Returns this security manager's internal delegate {@link SessionManager SessionManager}.
090 *
091 * @return this security manager's internal delegate {@link SessionManager SessionManager}.
092 * @see #setSessionManager(org.apache.shiro.session.mgt.SessionManager) setSessionManager
093 */
094 public SessionManager getSessionManager() {
095 return this.sessionManager;
096 }
097
098 /**
099 * Calls {@link org.apache.shiro.mgt.AuthorizingSecurityManager#afterCacheManagerSet() super.afterCacheManagerSet()} and then immediately calls
100 * {@link #applyCacheManagerToSessionManager() applyCacheManagerToSessionManager()} to ensure the
101 * <code>CacheManager</code> is applied to the SessionManager as necessary.
102 */
103 protected void afterCacheManagerSet() {
104 super.afterCacheManagerSet();
105 applyCacheManagerToSessionManager();
106 }
107
108 /**
109 * Ensures the internal delegate <code>SessionManager</code> is injected with the newly set
110 * {@link #setCacheManager CacheManager} so it may use it for its internal caching needs.
111 * <p/>
112 * Note: This implementation only injects the CacheManager into the SessionManager if the SessionManager
113 * instance implements the {@link CacheManagerAware CacheManagerAware} interface.
114 */
115 protected void applyCacheManagerToSessionManager() {
116 if (this.sessionManager instanceof CacheManagerAware) {
117 ((CacheManagerAware) this.sessionManager).setCacheManager(getCacheManager());
118 }
119 }
120
121 public Session start(SessionContext context) throws AuthorizationException {
122 return this.sessionManager.start(context);
123 }
124
125 public Session getSession(SessionKey key) throws SessionException {
126 return this.sessionManager.getSession(key);
127 }
128
129 public void destroy() {
130 LifecycleUtils.destroy(getSessionManager());
131 this.sessionManager = null;
132 }
133 }