Modified: shiro/site/publish/session-management.html
URL: 
http://svn.apache.org/viewvc/shiro/site/publish/session-management.html?rev=1766414&r1=1766413&r2=1766414&view=diff
==============================================================================
--- shiro/site/publish/session-management.html (original)
+++ shiro/site/publish/session-management.html Mon Oct 24 14:33:52 2016
@@ -78,8 +78,8 @@
 
         <div id="content">
 
-            <h1><a name="SessionManagement-SessionManagement"></a>Session 
Management</h1>
-
+            <a name="SessionManagement-SessionManagement"></a>
+<h1><a href="#session-management" name="session-management">Session 
Management</a></h1>
 <table align="right" width="275" style="margin-left: 20px; margin-bottom: 
20px; border-style: solid; border-width: 2px; border-color: navy" 
cellpadding="10px">
 
 <tr>
@@ -90,7 +90,7 @@
   <h3><a href="get-started.html">Getting Started</a></h3>
   <p>Resources, guides and tutorials for new Shiro users. </br><span 
style="font-size:11"><a href="get-started.html">Read More 
&gt;&gt;</a></span></p> 
        
-       <h3><a href="10-minute-tutorial.html">10-Minute Shiro Tutorial</a></h3>
+  <h3><a href="10-minute-tutorial.html">10-Minute Shiro Tutorial</a></h3>
   <p>Try Apache Shiro for yourself in under 10 minutes. </br><span 
style="font-size:11"><a href="10-minute-tutorial.html">Read More 
&gt;&gt;</a></span></p>
        
   <h3><a href="webapp-tutorial.html">Web App Tutorial</a></h3>
@@ -106,465 +106,611 @@
 </td>
 </tr>
 </table>
-
-<div class="toc">
-<ul><li><a href="#SessionManagement-UsingSessions">Using 
Sessions</a></li><li><a href="#SessionManagement-TheSessionManager">The 
SessionManager</a></li><ul><li><a 
href="#SessionManagement-SessionTimeout">Session Timeout</a></li><ul><li><a 
href="#SessionManagement-PerSessionTimeout">Per-Session 
Timeout</a></li></ul><li><a href="#SessionManagement-SessionListeners">Session 
Listeners</a></li><li><a href="#SessionManagement-SessionStorage">Session 
Storage</a></li><ul><li><a href="#SessionManagement-EHCacheSessionDAO">EHCache 
SessionDAO</a></li><ul><li><a 
href="#SessionManagement-EHCacheSessionCacheConfiguration">EHCache Session 
Cache Configuration</a></li><li><a 
href="#SessionManagement-EHCacheSessionCacheName">EHCache Session Cache 
Name</a></li></ul><li><a href="#SessionManagement-CustomSessionIDs">Custom 
Session IDs</a></li></ul><li><a 
href="#SessionManagement-SessionValidation%26Scheduling">Session Validation 
&amp; Scheduling</a></li><ul><li><a href="#SessionManagement-DefaultSession
 ValidationScheduler">Default SessionValidationScheduler</a></li><li><a 
href="#SessionManagement-CustomSessionValidationScheduler">Custom 
SessionValidationScheduler</a></li><li><a 
href="#SessionManagement-DisablingSessionValidation">Disabling Session 
Validation</a></li><li><a 
href="#SessionManagement-InvalidSessionDeletion">Invalid Session 
Deletion</a></li></ul></ul><li><a 
href="#SessionManagement-SessionClustering">Session 
Clustering</a></li><ul><li><a 
href="#SessionManagement-%7B%7BEnterpriseCacheSessionDAO%7D%7D"> 
<tt>EnterpriseCacheSessionDAO</tt></a></li><li><a 
href="#SessionManagement-EhcacheTerracotta">Ehcache + Terracotta</a></li><li><a 
href="#SessionManagement-Zookeeper">Zookeeper</a></li></ul><li><a 
href="#SessionManagement-SessionsandSubjectState">Sessions and Subject 
State</a></li><ul><li><a 
href="#SessionManagement-StatefulApplications%28Sessionsallowed%29">Stateful 
Applications (Sessions allowed)</a></li><li><a 
href="#SessionManagement-StatelessApplications%28Sessionles
 s%29">Stateless Applications (Sessionless)</a></li><ul><li><a 
href="#SessionManagement-DisablingSubjectStateSessionStorage">Disabling Subject 
State Session Storage</a></li></ul><li><a 
href="#SessionManagement-AHybridApproach">A Hybrid Approach</a></li><ul><li><a 
href="#SessionManagement-SessionStorageEvaluator">SessionStorageEvaluator</a></li><ul><li><a
 href="#SessionManagement-SubjectInspection">Subject 
Inspection</a></li></ul><li><a 
href="#SessionManagement-Configuration">Configuration</a></li></ul><li><a 
href="#SessionManagement-WebApplications">Web 
Applications</a></li></ul></ul></div>
-
+<ul>
+  <li><a href="#SessionManagement-UsingSessions">Using Sessions</a></li>
+  <li><a href="#SessionManagement-TheSessionManager">The SessionManager</a>
+    <ul>
+      <li>
+        <p><a href="#SessionManagement-SessionTimeout">Session Timeout</a></p>
+        <ul>
+          <li>
+          <p><a href="#SessionManagement-PerSessionTimeout">Per-Session 
Timeout</a></p></li>
+        </ul>
+      </li>
+      <li>
+      <p><a href="#SessionManagement-SessionListeners">Session 
Listeners</a></p></li>
+      <li><a href="#SessionManagement-SessionStorage">Session Storage</a>
+        <ul>
+          <li>
+            <p><a href="#SessionManagement-EHCacheSessionDAO">EHCache 
SessionDAO</a></p>
+            <ul>
+              <li><a 
href="#SessionManagement-EHCacheSessionCacheConfiguration">EHCache Session 
Cache Configuration</a></li>
+              <li><a href="#SessionManagement-EHCacheSessionCacheName">EHCache 
Session Cache Name</a></li>
+            </ul>
+          </li>
+          <li>
+          <p><a href="#SessionManagement-CustomSessionIDs">Custom Session 
IDs</a></p></li>
+        </ul>
+      </li>
+      <li>
+        <p><a href="#SessionManagement-SessionValidation%26Scheduling">Session 
Validation &amp; Scheduling</a></p>
+        <ul>
+          <li><a 
href="#SessionManagement-DefaultSessionValidationScheduler">Default 
SessionValidationScheduler</a></li>
+          <li><a 
href="#SessionManagement-CustomSessionValidationScheduler">Custom 
SessionValidationScheduler</a></li>
+          <li><a 
href="#SessionManagement-DisablingSessionValidation">Disabling Session 
Validation</a></li>
+          <li><a href="#SessionManagement-InvalidSessionDeletion">Invalid 
Session Deletion</a></li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li>
+    <p><a href="#SessionManagement-SessionClustering">Session 
Clustering</a></p>
+    <ul>
+      <li><a 
href="#SessionManagement-%7B%7BEnterpriseCacheSessionDAO%7D%7D"><code>EnterpriseCacheSessionDAO</code></a></li>
+      <li><a href="#SessionManagement-EhcacheTerracotta">Ehcache + 
Terracotta</a></li>
+      <li><a href="#SessionManagement-Zookeeper">Zookeeper</a></li>
+    </ul>
+  </li>
+  <li>
+    <p><a href="#SessionManagement-SessionsandSubjectState">Sessions and 
Subject State</a></p>
+    <ul>
+      <li><a 
href="#SessionManagement-StatefulApplications%28Sessionsallowed%29">Stateful 
Applications (Sessions allowed)</a></li>
+      <li><a 
href="#SessionManagement-StatelessApplications%28Sessionless%29">Stateless 
Applications (Sessionless)</a>
+        <ul>
+          <li>
+          <p><a 
href="#SessionManagement-DisablingSubjectStateSessionStorage">Disabling Subject 
State Session Storage</a></p></li>
+        </ul>
+      </li>
+      <li>
+        <p><a href="#SessionManagement-AHybridApproach">A Hybrid 
Approach</a></p>
+        <ul>
+          <li>
+            <p><a 
href="#SessionManagement-SessionStorageEvaluator">SessionStorageEvaluator</a></p>
+            <ul>
+              <li>
+              <p><a href="#SessionManagement-SubjectInspection">Subject 
Inspection</a></p></li>
+            </ul>
+          </li>
+          <li>
+          <p><a 
href="#SessionManagement-Configuration">Configuration</a></p></li>
+        </ul>
+      </li>
+      <li>
+      <p><a href="#SessionManagement-WebApplications">Web 
Applications</a></p></li>
+    </ul>
+  </li>
+</ul>
 <p>Apache Shiro offers something unique in the world of security frameworks: a 
complete enterprise-grade Session solution for any application, from the 
simplest command-line and smart phone applications to the largest clustered 
enterprise web applications.</p>
-
-<p>This has large implications for many applications - until Shiro, if you 
required session support, you were required to deploy your application in a web 
container or use EJB Stateful Session Beans.  Shiro's Session support is much 
simpler to use and manage than either of these two mechanisms, and it is 
available in any application, regardless of container.  </p>
-
-<p>And even if you deploy your application in a Servlet or EJB container, 
there are still compelling reasons to use Shiro's Session support instead of 
the container's.  Here is a list of the most desirable features provided by 
Shiro's session support:</p>
-
-<p><b>Features</b></p>
-
-<ul><li><b>POJO/J2SE based (IoC friendly)</b> - Everything in Shiro (including 
all aspects of Sessions and Session Management) is interface-based and 
implemented with POJOs.  This allows you to easily configure all session 
components with any JavaBeans-compatible configuration format, like JSON, YAML, 
Spring XML or similar mechanisms. You can also easily extend Shiro's components 
or write your own as necessary to fully customize session management 
functionality.</li></ul>
-
-
-<ul><li><b>Easy Custom Session Storage</b> - Because Shiro's Session objects 
are POJO-based, session data can be easily stored in any number of data 
sources.  This allows you to customize exactly where your application's session 
data resides - for example, the file system, in memory, in a networked 
distributed cache, a relational database, or proprietary data store.</li></ul>
-
-
-<ul><li><b>Container-Independent Clustering!</b> - Shiro's sessions can be 
easily clustered using any of the readily-available networked caching products, 
like Ehcache + Terracotta, Coherence, GigaSpaces, et. al.  This means you can 
configure session clustering for Shiro once and only once, and no matter what 
container you deploy to, your sessions will be clustered the same way.  No need 
for container-specific configuration!</li></ul>
-
-
-<ul><li><b>Heterogeneous Client Access</b> - Unlike EJB or Web sessions, Shiro 
sessions can be 'shared' across various client technologies.  For example, a 
desktop application could 'see' and 'share' the same physical session used by 
the same user in a web application.  We are unaware of any framework other than 
Shiro that can support this.</li></ul>
-
-
-<ul><li><b>Event Listeners</b> - Event listeners allow you to listen to 
lifecycle events during a session's lifetime.  You can listen for these events 
and react to them for custom application behavior - for example, updating a 
user record when their session expires.</li></ul>
-
-
-<ul><li><b>Host Address Retention</b> &#8211; Shiro Sessions retain the IP 
address or host name of the host from where the session was initiated.  This 
allows you to determine where the user is located and react accordingly (often 
useful in intranet environments where IP association is 
deterministic).</li></ul>
-
-
-<ul><li><b>Inactivity/Expiration Support</b> &#8211; Sessions expire due to 
inactivity as expected, but they can be prolonged via a <tt>touch()</tt> method 
to keep them 'alive' if desired.  This is useful in Rich Internet Application 
(RIA) environments where the user might be using a desktop application, but may 
not be regularly communicating with the server, but the server session should 
not expire.</li></ul>
-
-
-<ul><li><b>Transparent Web Use</b> - Shiro's web support fully implements and 
supports the Servlet 2.5 specification for Sessions (<tt>HttpSession</tt> 
interface and all of it's associated APIs). This means you can use Shiro 
sessions in existing web applications and you don't need to change any of your 
existing web code.</li></ul>
-
-
-<ul><li><b>Can be used for SSO</b> - Because Shiro session's are POJO based, 
they are easily stored in any data source, and they can be 'shared' across 
applications if needed.  We call this 'poor man's SSO', and it can be used to 
provide a simple sign-on experience since the shared session can retain 
authentication state.</li></ul>
-
-
-<h2><a name="SessionManagement-UsingSessions"></a>Using Sessions</h2>
-
-<p>Like almost everything else in Shiro, you acquire a <tt>Session</tt> by 
interacting with the currently executing <tt>Subject</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-java">
-Subject currentUser = SecurityUtils.getSubject();
+<p>This has large implications for many applications - until Shiro, if you 
required session support, you were required to deploy your application in a web 
container or use EJB Stateful Session Beans. Shiro&rsquo;s Session support is 
much simpler to use and manage than either of these two mechanisms, and it is 
available in any application, regardless of container.</p>
+<p>And even if you deploy your application in a Servlet or EJB container, 
there are still compelling reasons to use Shiro&rsquo;s Session support instead 
of the container&rsquo;s. Here is a list of the most desirable features 
provided by Shiro&rsquo;s session support:</p>
+<p><strong>Features</strong></p>
+<ul>
+  <li>
+  <p><strong>POJO/J2SE based (IoC friendly)</strong> - Everything in Shiro 
(including all aspects of Sessions and Session Management) is interface-based 
and implemented with POJOs. This allows you to easily configure all session 
components with any JavaBeans-compatible configuration format, like JSON, YAML, 
Spring XML or similar mechanisms. You can also easily extend Shiro&rsquo;s 
components or write your own as necessary to fully customize session management 
functionality.</p></li>
+  <li>
+  <p><strong>Easy Custom Session Storage</strong> - Because Shiro&rsquo;s 
Session objects are POJO-based, session data can be easily stored in any number 
of data sources. This allows you to customize exactly where your 
application&rsquo;s session data resides - for example, the file system, in 
memory, in a networked distributed cache, a relational database, or proprietary 
data store.</p></li>
+  <li>
+  <p><strong>Container-Independent Clustering!</strong> - Shiro&rsquo;s 
sessions can be easily clustered using any of the readily-available networked 
caching products, like Ehcache + Terracotta, Coherence, GigaSpaces, et. al. 
This means you can configure session clustering for Shiro once and only once, 
and no matter what container you deploy to, your sessions will be clustered the 
same way. No need for container-specific configuration!</p></li>
+  <li>
+  <p><strong>Heterogeneous Client Access</strong> - Unlike EJB or Web 
sessions, Shiro sessions can be &lsquo;shared&rsquo; across various client 
technologies. For example, a desktop application could &lsquo;see&rsquo; and 
&lsquo;share&rsquo; the same physical session used by the same user in a web 
application. We are unaware of any framework other than Shiro that can support 
this.</p></li>
+  <li>
+  <p><strong>Event Listeners</strong> - Event listeners allow you to listen to 
lifecycle events during a session&rsquo;s lifetime. You can listen for these 
events and react to them for custom application behavior - for example, 
updating a user record when their session expires.</p></li>
+  <li>
+  <p><strong>Host Address Retention</strong> – Shiro Sessions retain the IP 
address or host name of the host from where the session was initiated. This 
allows you to determine where the user is located and react accordingly (often 
useful in intranet environments where IP association is deterministic).</p></li>
+  <li>
+  <p><strong>Inactivity/Expiration Support</strong> – Sessions expire due to 
inactivity as expected, but they can be prolonged via a <code>touch()</code> 
method to keep them &lsquo;alive&rsquo; if desired. This is useful in Rich 
Internet Application (RIA) environments where the user might be using a desktop 
application, but may not be regularly communicating with the server, but the 
server session should not expire.</p></li>
+  <li>
+  <p><strong>Transparent Web Use</strong> - Shiro&rsquo;s web support fully 
implements and supports the Servlet 2.5 specification for Sessions 
(<code>HttpSession</code> interface and all of it&rsquo;s associated APIs). 
This means you can use Shiro sessions in existing web applications and you 
don&rsquo;t need to change any of your existing web code.</p></li>
+  <li>
+  <p><strong>Can be used for SSO</strong> - Because Shiro session&rsquo;s are 
POJO based, they are easily stored in any data source, and they can be 
&lsquo;shared&rsquo; across applications if needed. We call this &lsquo;poor 
man&rsquo;s SSO&rsquo;, and it can be used to provide a simple sign-on 
experience since the shared session can retain authentication state.</p></li>
+</ul>
+<a name="SessionManagement-UsingSessions"></a>
+<h2><a href="#using-sessions" name="using-sessions">Using Sessions</a></h2>
+<p>Like almost everything else in Shiro, you acquire a <code>Session</code> by 
interacting with the currently executing <code>Subject</code>:</p>
+<pre><code class="java">Subject currentUser = SecurityUtils.getSubject();
 
 Session session = currentUser.getSession();
-session.setAttribute( <span class="code-quote">"someKey"</span>, someValue);
-</pre>
-</div></div>
-
-<p>The <tt>subject.getSession()</tt> method is a shortcut for calling 
<tt>currentUser.getSubject(true)</tt>.  </p>
-
-<p>For those familiar with <tt>HttpServletRequest</tt> API, the 
<tt>Suject.getSession(boolean create)</tt> method functions the same way as the 
<tt>HttpServletRequest.getSession(boolean create)</tt> method:</p>
-<ul><li>If the <tt>Subject</tt> already has a <tt>Session</tt>, the boolean 
argument is ignored and the <tt>Session</tt> is returned immediately</li><li>If 
the <tt>Subject</tt> does not yet have a <tt>Session</tt> and the 
<tt>create</tt> boolean argument is <tt>true</tt>, a new session will be 
created and returned.</li><li>If the <tt>Subject</tt> does not yet have a 
<tt>Session</tt> and the <tt>create</tt> boolean argument is <tt>false</tt>, a 
new session will not be created and <tt>null</tt> is returned.</li></ul>
-
-
-#tip('Any Application', '<tt>getSession</tt> calls work in any application, 
even non-web applications.')
-
-<p><tt>subject.getSession(false)</tt> can be used to good effect when 
developing framework code to ensure a Session isn't created unnecessarily.</p>
-
-<p>Once you acquire a Subject's <tt>Session</tt> you can do many things with 
it, like set or retrieve attributes, set its timeout, and more.  See the <a 
class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/Session.html">Session 
JavaDoc</a> to see what is possible with an individual session.</p>
-
-<h2><a name="SessionManagement-TheSessionManager"></a>The SessionManager</h2>
-
-<p>The SessionManager, as its name might imply, manages Sessions for 
<em>all</em> subjects in an application - creation, deletion, inactivity and 
validation, etc.  Like other core architectural components in Shiro, the 
<tt>SessionManager</tt> is a top-level component maintained by the 
<tt>SecurityManager</tt>.</p>
-
-<p>The default <tt>SecurityManager</tt> implementation defaults to using a 
<tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/mgt/DefaultSecurityManager.html">DefaultSessionManager</a></tt>
 out of the box.  The <tt>DefaultSessionManager</tt> implementation provides 
all of the enterprise-grade session management features needed for an 
application, like Session validation, orphan cleanup, etc.  This can be used in 
any application.</p>
-
-#info('Web Applications', 'Web applications use different 
<tt>SessionManager</tt> implementations.  Please see the <a href="web.html" 
title="Web">Web</a> documentation for web-specific Session Management 
information.')
-
-<p>Like all other components managed by the <tt>SecurityManager</tt>, the 
<tt>SessionManager</tt> can be acquired or set via JavaBeans-style 
getter/setter methods on all of Shiro's default <tt>SecurityManager</tt> 
implementations (<tt>getSessionManager()</tt>/<tt>setSessionManager()</tt>).  
Or for example, if using <tt>shiro.ini</tt> <a href="configuration.html" 
title="Configuration">Configuration</a>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring a new 
SessionManager in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+session.setAttribute( &quot;someKey&quot;, someValue);
+</code></pre>
+<p>The <code>subject.getSession()</code> method is a shortcut for calling 
<code>currentUser.getSubject(true)</code>.</p>
+<p>For those familiar with <code>HttpServletRequest</code> API, the 
<code>Suject.getSession(boolean create)</code> method functions the same way as 
the <code>HttpServletRequest.getSession(boolean create)</code> method:</p>
+<ul>
+  <li>If the <code>Subject</code> already has a <code>Session</code>, the 
boolean argument is ignored and the <code>Session</code> is returned 
immediately</li>
+  <li>If the <code>Subject</code> does not yet have a <code>Session</code> and 
the <code>create</code> boolean argument is <code>true</code>, a new session 
will be created and returned.</li>
+  <li>If the <code>Subject</code> does not yet have a <code>Session</code> and 
the <code>create</code> boolean argument is <code>false</code>, a new session 
will not be created and <code>null</code> is returned.</li>
+</ul>
+<div class="panelMacro">
+    <table class="tipMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody><tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-check-square-o"></i>
+            </td>
+            <td colspan="1" rowspan="1">
+                <b>Any Application</b>
+                <br clear="none">
+                <code>getSession</code> calls work in any application, even 
non-web applications.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<p><code>subject.getSession(false)</code> can be used to good effect when 
developing framework code to ensure a Session isn&rsquo;t created 
unnecessarily.</p>
+<p>Once you acquire a Subject&rsquo;s <code>Session</code> you can do many 
things with it, like set or retrieve attributes, set its timeout, and more. See 
the <a 
href="static/current/apidocs/org/apache/shiro/session/Session.html">Session 
JavaDoc</a> to see what is possible with an individual session.</p>
+<a name="SessionManagement-TheSessionManager"></a>
+<h2><a href="#the-sessionmanager" name="the-sessionmanager">The 
SessionManager</a></h2>
+<p>The SessionManager, as its name might imply, manages Sessions for 
<em>all</em> subjects in an application - creation, deletion, inactivity and 
validation, etc. Like other core architectural components in Shiro, the 
<code>SessionManager</code> is a top-level component maintained by the 
<code>SecurityManager</code>.</p>
+<p>The default <code>SecurityManager</code> implementation defaults to using a 
<a 
href="static/current/apidocs/org/apache/shiro/mgt/DefaultSecurityManager.html"><code>DefaultSessionManager</code></a>
 out of the box. The <code>DefaultSessionManager</code> implementation provides 
all of the enterprise-grade session management features needed for an 
application, like Session validation, orphan cleanup, etc. This can be used in 
any application.</p>
+<div class="panelMacro">
+    <table class="infoMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+
+
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-info-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Web Applications</b>
+                <br clear="none">
+                Web applications use different <code>SessionManager</code> 
implementations. Please see the <a href="web.html">Web</a> documentation for 
web-specific Session Management information.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<p>Like all other components managed by the <code>SecurityManager</code>, the 
<code>SessionManager</code> can be acquired or set via JavaBeans-style 
getter/setter methods on all of Shiro&rsquo;s default 
<code>SecurityManager</code> implementations 
(<code>getSessionManager()</code>/<code>setSessionManager()</code>). Or for 
example, if using <code>shiro.ini</code> <a href="configuration.html" 
title="Configuration">Configuration</a>:</p>
+<p><strong>Configuring a new SessionManager in shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 sessionManager = com.foo.my.SessionManagerImplementation
 securityManager.sessionManager = $sessionManager
-</pre>
-</div></div>
-
-<p>But creating a <tt>SessionManager</tt> from scratch is a complicated task 
and not something that most people will want to do themselves.  Shiro's 
out-of-the-box <tt>SessionManager</tt> implementations are highly customizable 
and configurable and will suit most needs.  Most of the rest of this 
documentation assumes that you will be using Shiro's default 
<tt>SessionManager</tt> implementations when covering configuration options, 
but note that you can essentially create or plug-in nearly anything you 
wish.</p>
-
-<p><a name="SessionManagement-sessionTimeout"></a></p>
-<h3><a name="SessionManagement-SessionTimeout"></a>Session Timeout</h3>
-
-<p>By default, Shiro's <tt>SessionManager</tt> implementations default to a 30 
minute session timeout.  That is, if any <tt>Session</tt> created remains idle 
(unused, where its <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/Session.html#getLastAccessTime()">lastAccessedTime</a></tt>
 isn't updated) for 30 minutes or more, the <tt>Session</tt> is considered 
expired and will not be allowed to be used anymore.</p>
-
-<p>You can set the default <tt>SessionManager</tt> implementation's 
<tt>globalSessionTimeout</tt> property to define the default timeout value for 
all sessions.  For example, if you wanted the timeout to be an hour instead of 
30 minutes:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Setting the Default Session 
Timeout in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<p>But creating a <code>SessionManager</code> from scratch is a complicated 
task and not something that most people will want to do themselves. 
Shiro&rsquo;s out-of-the-box <code>SessionManager</code> implementations are 
highly customizable and configurable and will suit most needs. Most of the rest 
of this documentation assumes that you will be using Shiro&rsquo;s default 
<code>SessionManager</code> implementations when covering configuration 
options, but note that you can essentially create or plug-in nearly anything 
you wish.</p>
+<a name="SessionManagement-sessionTimeout"></a>
+<a name="SessionManagement-SessionTimeout"></a>
+<h3><a href="#session-timeout" name="session-timeout">Session Timeout</a></h3>
+<p>By default, Shiro&rsquo;s <code>SessionManager</code> implementations 
default to a 30 minute session timeout. That is, if any <code>Session</code> 
created remains idle (unused, where its <a 
href="static/current/apidocs/org/apache/shiro/session/Session.html#getLastAccessTime--"><code>lastAccessedTime</code></a>
 isn&rsquo;t updated) for 30 minutes or more, the <code>Session</code> is 
considered expired and will not be allowed to be used anymore.</p>
+<p>You can set the default <code>SessionManager</code> implementation&rsquo;s 
<code>globalSessionTimeout</code> property to define the default timeout value 
for all sessions. For example, if you wanted the timeout to be an hour instead 
of 30 minutes:</p>
+<p><strong>Setting the Default Session Timeout in shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 # 3,600,000 milliseconds = 1 hour
 securityManager.sessionManager.globalSessionTimeout = 3600000
-
-</pre>
-</div></div>
-
-<h4><a name="SessionManagement-PerSessionTimeout"></a>Per-Session Timeout</h4>
-
-<p>The above <tt>globalSessionTimeout</tt> value is the default for all newly 
created <tt>Sessions</tt>.  You can control session timeout on a per-Session 
basis by setting the individual Session's <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/Session.html#setTimeout(long)">timeout</a></tt>
 value.  Like the above <tt>globalSessionTimeout</tt>, the value is time in 
<b>milliseconds</b> (not seconds).</p>
-
-<h3><a name="SessionManagement-SessionListeners"></a>Session Listeners</h3>
-
-<p>Shiro supports the notion of a <tt>SessionListener</tt> to allow you to 
react to important session events as they occur.  You can implement the <tt><a 
class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/SessionListener.html">SessionListener</a></tt>
 interface (or extend the convenience <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/SessionListenerAdapter.html">SessionListenerAdapter</a></tt>)
 and react to session operations accordingly.</p>
-
-<p>As the default <tt>SessionManager</tt> <tt>sessionListeners</tt> property 
is a collection, you can configure the <tt>SessionManager</tt> with one or more 
of your listener implementations like any other collection in 
<tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>SessionListener Configuration 
in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<a name="SessionManagement-PerSessionTimeout"></a>
+<h4>Per-Session Timeout</h4>
+<p>The above <code>globalSessionTimeout</code> value is the default for all 
newly created <code>Sessions</code>. You can control session timeout on a 
per-Session basis by setting the individual Session&rsquo;s <a 
href="static/current/apidocs/org/apache/shiro/session/Session.html#setTimeout-long-"><code>timeout</code></a>
 value. Like the above <code>globalSessionTimeout</code>, the value is time in 
<strong>milliseconds</strong> (not seconds).</p>
+<a name="SessionManagement-SessionListeners"></a>
+<h3><a href="#session-listeners" name="session-listeners">Session 
Listeners</a></h3>
+<p>Shiro supports the notion of a <code>SessionListener</code> to allow you to 
react to important session events as they occur. You can implement the <a 
href="static/current/apidocs/org/apache/shiro/session/SessionListener.html"><code>SessionListener</code></a>
 interface (or extend the convenience <a 
href="static/current/apidocs/org/apache/shiro/session/SessionListenerAdapter.html"><code>SessionListenerAdapter</code></a>)
 and react to session operations accordingly.</p>
+<p>As the default <code>SessionManager</code> <code>sessionListeners</code> 
property is a collection, you can configure the <code>SessionManager</code> 
with one or more of your listener implementations like any other collection in 
<code>shiro.ini</code>:</p>
+<p><strong>SessionListener Configuration in shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 aSessionListener = com.foo.my.SessionListener
 anotherSessionListener = com.foo.my.OtherSessionListener
 
 securityManager.sessionManager.sessionListeners = $aSessionListener, 
$anotherSessionListener, etc.
-</pre>
-</div></div>
-
-#info('All Session Events', '<tt>SessionListeners</tt> are notified when an 
event occurs for <em>any</em> session - not just for a particular session.')
-
-<p><a name="SessionManagement-sessionstorage"></a></p>
-<h3><a name="SessionManagement-SessionStorage"></a>Session Storage</h3>
-
-<p>Whenever a session is created or updated, its data needs to persisted to a 
storage location so it is accessible by the application at a later time.  
Similarly, when a session is invalid and longer being used, it needs to be 
deleted from storage so the session data store space is not exhausted.  The 
<tt>SessionManager</tt> implementations delegate these 
Create/Read/Update/Delete (CRUD) operations to an internal component, the 
<tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/SessionDAO.html">SessionDAO</a></tt>,
 which reflects the <a class="external-link" 
href="https://en.wikipedia.org/wiki/Data_access_object"; rel="nofollow">Data 
Access Object (DAO)</a> design pattern.</p>
-
-<p>The power of the SessionDAO is that you can implement this interface to 
communicate with <em>any</em> data store you wish.  This means your session 
data can reside in memory, on the file system, in a relational database or 
NoSQL data store, or any other location you need.  You have control over 
persistence behavior.</p>
-
-<p>You can configure any <tt>SessionDAO</tt> implementation as a property on 
the default <tt>SessionManager</tt> instance. For example, in shiro.ini:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring a SessionDAO in 
shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<div class="panelMacro">
+    <table class="infoMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+
+
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-info-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>All Session Events</b>
+                <br clear="none">
+                <code>SessionListeners</code> are notified when an event 
occurs for <i>any</i> session - not just for a particular session.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-sessionstorage"></a>
+<a name="SessionManagement-SessionStorage"></a>
+<h3><a href="#session-storage" name="session-storage">Session Storage</a></h3>
+<p>Whenever a session is created or updated, its data needs to persisted to a 
storage location so it is accessible by the application at a later time. 
Similarly, when a session is invalid and longer being used, it needs to be 
deleted from storage so the session data store space is not exhausted. The 
<code>SessionManager</code> implementations delegate these 
Create/Read/Update/Delete (CRUD) operations to an internal component, the <a 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/SessionDAO.html"><code>SessionDAO</code></a>,
 which reflects the <a 
href="https://en.wikipedia.org/wiki/Data_access_object";>Data Access Object 
(DAO)</a> design pattern.</p>
+<p>The power of the SessionDAO is that you can implement this interface to 
communicate with <em>any</em> data store you wish. This means your session data 
can reside in memory, on the file system, in a relational database or NoSQL 
data store, or any other location you need. You have control over persistence 
behavior.</p>
+<p>You can configure any <code>SessionDAO</code> implementation as a property 
on the default <code>SessionManager</code> instance. For example, in 
shiro.ini:</p>
+<p><strong>Configuring a SessionDAO in shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 sessionDAO = com.foo.my.SessionDAO
 securityManager.sessionManager.sessionDAO = $sessionDAO
+</code></pre>
+<p>However, as you might expect, Shiro already has some good 
<code>SessionDAO</code> implementations that you can use out of the box or 
subclass for your own needs.<br/><a 
name="SessionManagement-websessionmanagersessiondao"></a></p>
+<div class="panelMacro">
+    <table class="noteMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-warning"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Web Applications</b>
+                <br clear="none">
+                The above <code>securityManager.sessionManager.sessionDAO = 
$sessionDAO</code> assignment only works when using a Shiro native session 
manager. Web applications by default do not use a native session manager and 
instead retain the Servlet Container's default session manager which does not 
support a SessionDAO. If you would like to enable a SessionDAO in a web-based 
application for custom session storage or session clustering, you will have to 
first configure a native web session manager. For example:
 
-</pre>
-</div></div>
-
-<p>However, as you might expect, Shiro already has some good 
<tt>SessionDAO</tt> implementations that you can use out of the box or subclass 
for your own needs.<br clear="none">
-<a name="SessionManagement-websessionmanagersessiondao"></a></p>
-#warning('Web Applications', 'The above 
<tt>securityManager.sessionManager.sessionDAO = $sessionDAO</tt> assignment 
only works when using a Shiro native session manager.  Web applications by 
default do not use a native session manager and instead retain the Servlet 
Container's default session manager which does not support a SessionDAO.  If 
you would like to enable a SessionDAO in a web-based application for custom 
session storage or session clustering, you will have to first configure a 
native web session manager.  For example:
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-java">
+<div><pre><code class="ini">
 [main]
 ...
 sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
 securityManager.sessionManager = $sessionManager
 
-# Configure a SessionDAO and then set it:
+; Configure a SessionDAO and then set it:
 securityManager.sessionManager.sessionDAO = $sessionDAO
-</pre>
-</div></div>')
-
-#danger('Configure a SessionDAO!', 'Shiro''s default configuration native 
SessionManagers use <b><em>in-memory-only</em></b> Session storage.  This is 
unsuitable for most production applications.  Most production applications will 
want to either configure the provided EHCache support (see below) or provide 
their own <tt>SessionDAO</tt> implementation.
-<p>Note that web applications use a servlet-container-based SessionManager by 
default and do not have this issue.  This is only an issue when using a Shiro 
native SessionManager.</p>')
-
-<p><a name="SessionManagement-ehcachesessiondao"></a></p>
-<h4><a name="SessionManagement-EHCacheSessionDAO"></a>EHCache SessionDAO</h4>
-
-<p>EHCache is not enabled by default, but if you do not plan on implementing 
your own <tt>SessionDAO</tt>, it is <b>highly</b> recommended that you enable 
the EHCache support for Shiro's SessionManagement.  The EHCache SessionDAO will 
store sessions in memory and support overflow to disk if memory becomes 
constrained.  This is highly desirable for production applications to ensure 
that you don't randomly 'lose' sessions at runtime.</p>
-
-#tip('Use EHCache as your default', 'If you're not writing a custom 
<tt>SessionDAO</tt>, definitely enable EHCache in your Shiro configuration.  
EHCache can also be beneficial beyond Sessions, caching authentication and 
authorization data as well.  See the <a href="caching.html" 
title="Caching">Caching</a> documentation for more information.')
-#tip('Container-Independent Session Clustering', 'EHCache is also a nice 
choice if you quickly need container-independent session clustering. You can 
transparently plug in <a class="external-link" 
href="http://www.terracotta.org/"; rel="nofollow">TerraCotta</a> behind EHCache 
and have a container-independent clustered session cache.  No more worrying 
about Tomcat, JBoss, Jetty, WebSphere or WebLogic specific session clustering 
ever again!')
-<p>Enabling EHCache for sessions is very easy.  First, ensure that you have 
the <tt>shiro-ehcache-&lt;version&gt;.jar</tt> file in your classpath (see the 
<a href="download.html" title="Download">Download</a> page or use Maven or 
Ant+Ivy). </p>
 
-<p>Once in the classpath, this first <tt>shiro.ini</tt> example shows you how 
to use EHCache for all of Shiro's caching needs (not just Session support):</p>
 
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring EHCache for all 
of Shiro's caching needs in shiro.ini</b></div><div class="codeContent 
panelContent">
-<pre class="code-java">
-[main]
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+</code></pre></div>
+<div class="panelMacro">
+    <table class="warningMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-exclamation-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Configure a SessionDAO!</b>
+                <br clear="none">
+                Shiro's default configuration native SessionManagers use 
<strong>in-memory-only</strong> Session storage. This is unsuitable for most 
production applications. Most production applications will want to either 
configure the provided EHCache support (see below) or provide their own 
<code>SessionDAO</code> implementation.
+
+Note that web applications use a servlet-container-based SessionManager by 
default and do not have this issue. This is only an issue when using a Shiro 
native SessionManager.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-ehcachesessiondao"></a>
+<a name="SessionManagement-EHCacheSessionDAO"></a>
+<h4><a href="#ehcache-sessiondao" name="ehcache-sessiondao">EHCache 
SessionDAO</a></h4>
+<p>EHCache is not enabled by default, but if you do not plan on implementing 
your own <code>SessionDAO</code>, it is <strong>highly</strong> recommended 
that you enable the EHCache support for Shiro&rsquo;s SessionManagement. The 
EHCache SessionDAO will store sessions in memory and support overflow to disk 
if memory becomes constrained. This is highly desirable for production 
applications to ensure that you don&rsquo;t randomly &lsquo;lose&rsquo; 
sessions at runtime.</p>
+<div class="panelMacro">
+    <table class="tipMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody><tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-check-square-o"></i>
+            </td>
+            <td colspan="1" rowspan="1">
+                <b>Use EHCache as your default</b>
+                <br clear="none">
+                If you're not writing a custom <code>SessionDAO</code>, 
definitely enable EHCache in your Shiro configuration. EHCache can also be 
beneficial beyond Sessions, caching authentication and authorization data as 
well. See the <a href="caching.html">Caching</a> documentation for more 
information.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<div class="panelMacro">
+    <table class="tipMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody><tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-check-square-o"></i>
+            </td>
+            <td colspan="1" rowspan="1">
+                <b>Container-Independent Session Clustering</b>
+                <br clear="none">
+                EHCache is also a nice choice if you quickly need 
container-independent session clustering. You can transparently plug in <a 
href="http://www.terracotta.org/";>TerraCotta</a> behind EHCache and have a 
container-independent clustered session cache. No more worrying about Tomcat, 
JBoss, Jetty, WebSphere or WebLogic specific session clustering ever again!
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<p>Enabling EHCache for sessions is very easy. First, ensure that you have the 
<code>shiro-ehcache-&lt;version&gt;.jar</code> file in your classpath (see the 
<a href="download.html" title="Download">Download</a> page or use Maven or 
Ant+Ivy).</p>
+<p>Once in the classpath, this first <code>shiro.ini</code> example shows you 
how to use EHCache for all of Shiro&rsquo;s caching needs (not just Session 
support):</p>
+<p><strong>Configuring EHCache for all of Shiro&rsquo;s caching needs in 
shiro.ini</strong></p>
+<pre><code class="ini">[main]
 
 sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
 securityManager.sessionManager.sessionDAO = $sessionDAO
 
 cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
 securityManager.cacheManager = $cacheManager
-
-</pre>
-</div></div>
-
-<p>The final line, <tt>securityManager.cacheManager = $cacheManager</tt>, 
configures a <tt>CacheManager</tt> for all of Shiro's needs.  This 
<tt>CacheManager</tt> instance will propagate down to the <tt>SessionDAO</tt> 
automatically (by nature of <tt>EnterpriseCacheSessionDAO</tt> implementing the 
<tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/cache/CacheManagerAware.html">CacheManagerAware</a></tt>
 interface).</p>
-
-<p>Then, when the <tt>SessionManager</tt> asks the 
<tt>EnterpriseCacheSessionDAO</tt> to persist a <tt>Session</tt>, it will use 
an EHCache-backed <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/cache/Cache.html">Cache</a></tt> 
implementation to store the Session data.</p>
-
-#info('Web Applications', 'Don't forget that assigning a <tt>SessionDAO</tt> 
is a feature when using Shiro native SessionManager implementations.  Web 
applications by default use a Servlet container-based SessionManager which does 
not support a <tt>SessionDAO</tt>.  Configure a native web SessionManager as <a 
href="#SessionManagement-websessionmanagersessiondao">explained above</a> if 
you want to use Ehcache-based session storage in a web application.')
-
-<p><a name="SessionManagement-ehcachesessioncacheconfiguration"></a></p>
-<h5><a name="SessionManagement-EHCacheSessionCacheConfiguration"></a>EHCache 
Session Cache Configuration</h5>
-
-<p>By default, the <tt>EhCacheManager</tt> uses a Shiro-specific <tt><a 
class="external-link" 
href="https://github.com/apache/shiro/blob/master/support/ehcache/src/main/resources/org/apache/shiro/cache/ehcache/ehcache.xml";>ehcache.xml</a></tt>
 file that sets up the Session cache region and the necessary settings to 
ensure Sessions are stored and retrieved properly.</p>
-
-<p>However, if you wish to change the cache settings, or configure your own 
<tt>ehcache.xml</tt> or EHCache <tt>net.sf.ehcache.CacheManager</tt> instance, 
you will need to configure the cache region to ensure that Sessions are handled 
correctly.</p>
-
-<p>If you look at the default <tt><a class="external-link" 
href="https://github.com/apache/shiro/blob/master/support/ehcache/src/main/resources/org/apache/shiro/cache/ehcache/ehcache.xml";>ehcache.xml</a></tt>
 file, you will see the following <tt>shiro-activeSessionCache</tt> cache 
configuration:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-xml">
-&lt;cache name=<span class="code-quote">"shiro-activeSessionCache"</span>
-       maxElementsInMemory=<span class="code-quote">"10000"</span>
-       overflowToDisk=<span class="code-quote">"true"</span>
-       eternal=<span class="code-quote">"true"</span>
-       timeToLiveSeconds=<span class="code-quote">"0"</span>
-       timeToIdleSeconds=<span class="code-quote">"0"</span>
-       diskPersistent=<span class="code-quote">"true"</span>
-       diskExpiryThreadIntervalSeconds=<span 
class="code-quote">"600"</span>/&gt;
-</pre>
-</div></div>
-
-<p>If you wish to use your own <tt>ehcache.xml</tt> file, ensure that you have 
defined a similar cache entry for Shiro's needs.  Most likely you might change 
the <tt>maxElementsInMemory</tt> attribute value to meet your needs.  However, 
it is very important that at least the following two attributes exist (and are 
not changed) in your own configuration:</p>
-
-<ul><li><tt>overflowToDisk="true"</tt> - this ensures that if you run out of 
process memory, sessions won't be lost and can serialized to 
disk</li><li><tt>eternal="true"</tt> - ensures that cache entries (Session 
instances) are never expired or expunged automatically by the cache. This is 
necessary because Shiro does its own validation based on a scheduled process 
(see "Session Validation &amp; Scheduling" below).  If we turned this off, the 
cache would likely evict Sessions without Shiro knowing about it, which could 
cause problems.</li></ul>
-
-
-<h5><a name="SessionManagement-EHCacheSessionCacheName"></a>EHCache Session 
Cache Name</h5>
-
-<p>By default, the <tt>EnterpriseCacheSessionDAO</tt> asks the 
<tt>CacheManager</tt> for a <tt>Cache</tt> named 
"<tt>shiro-activeSessionCache</tt>".  This cache name/region is expected to be 
configured in <tt>ehcache.xml</tt>, as mentioned above.</p>
-
-<p>If you want to use a different name instead of this default, you can 
configure that name on the <tt>EnterpriseCacheSessionDAO</tt>, for example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring the cache name 
for Shiro's active session cache in shiro.ini</b></div><div class="codeContent 
panelContent">
-<pre class="code-java">
-[main]
-...
+</code></pre>
+<p>The final line, <code>securityManager.cacheManager = $cacheManager</code>, 
configures a <code>CacheManager</code> for all of Shiro&rsquo;s needs. This 
<code>CacheManager</code> instance will propagate down to the 
<code>SessionDAO</code> automatically (by nature of 
<code>EnterpriseCacheSessionDAO</code> implementing the <a 
href="static/current/apidocs/org/apache/shiro/cache/CacheManagerAware.html"><code>CacheManagerAware</code></a>
 interface).</p>
+<p>Then, when the <code>SessionManager</code> asks the 
<code>EnterpriseCacheSessionDAO</code> to persist a <code>Session</code>, it 
will use an EHCache-backed <a 
href="static/current/apidocs/org/apache/shiro/cache/Cache.html"><code>Cache</code></a>
 implementation to store the Session data.</p>
+<div class="panelMacro">
+    <table class="infoMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+
+
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-info-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Web Applications</b>
+                <br clear="none">
+                Don't forget that assigning a <code>SessionDAO</code> is a 
feature when using Shiro native SessionManager implementations. Web 
applications by default use a Servlet container-based SessionManager which does 
not support a <code>SessionDAO</code>. Configure a native web SessionManager as 
<a href="#SessionManagement-websessionmanagersessiondao">explained above</a> if 
you want to use Ehcache-based session storage in a web application.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-ehcachesessioncacheconfiguration"></a>
+<a name="SessionManagement-EHCacheSessionCacheConfiguration"></a>
+<h5><a href="#ehcache-session-cache-configuration" 
name="ehcache-session-cache-configuration">EHCache Session Cache 
Configuration</a></h5>
+<p>By default, the <code>EhCacheManager</code> uses a Shiro-specific <a 
href="https://github.com/apache/shiro/blob/master/support/ehcache/src/main/resources/org/apache/shiro/cache/ehcache/ehcache.xml";><code>ehcache.xml</code></a>
 file that sets up the Session cache region and the necessary settings to 
ensure Sessions are stored and retrieved properly.</p>
+<p>However, if you wish to change the cache settings, or configure your own 
<code>ehcache.xml</code> or EHCache <code>net.sf.ehcache.CacheManager</code> 
instance, you will need to configure the cache region to ensure that Sessions 
are handled correctly.</p>
+<p>If you look at the default <a 
href="https://github.com/apache/shiro/blob/master/support/ehcache/src/main/resources/org/apache/shiro/cache/ehcache/ehcache.xml";><code>ehcache.xml</code></a>
 file, you will see the following <code>shiro-activeSessionCache</code> cache 
configuration:</p>
+<pre><code class="xml">&lt;cache name=&quot;shiro-activeSessionCache&quot;
+       maxElementsInMemory=&quot;10000&quot;
+       overflowToDisk=&quot;true&quot;
+       eternal=&quot;true&quot;
+       timeToLiveSeconds=&quot;0&quot;
+       timeToIdleSeconds=&quot;0&quot;
+       diskPersistent=&quot;true&quot;
+       diskExpiryThreadIntervalSeconds=&quot;600&quot;/&gt;
+</code></pre>
+<p>If you wish to use your own <code>ehcache.xml</code> file, ensure that you 
have defined a similar cache entry for Shiro&rsquo;s needs. Most likely you 
might change the <code>maxElementsInMemory</code> attribute value to meet your 
needs. However, it is very important that at least the following two attributes 
exist (and are not changed) in your own configuration:</p>
+<ul>
+  <li><code>overflowToDisk=&quot;true&quot;</code> - this ensures that if you 
run out of process memory, sessions won&rsquo;t be lost and can serialized to 
disk</li>
+  <li><code>eternal=&quot;true&quot;</code> - ensures that cache entries 
(Session instances) are never expired or expunged automatically by the cache. 
This is necessary because Shiro does its own validation based on a scheduled 
process (see &ldquo;Session Validation &amp; Scheduling&rdquo; below). If we 
turned this off, the cache would likely evict Sessions without Shiro knowing 
about it, which could cause problems.</li>
+</ul>
+<a name="SessionManagement-EHCacheSessionCacheName"></a>
+<h5><a href="#ehcache-session-cache-name" 
name="ehcache-session-cache-name">EHCache Session Cache Name</a></h5>
+<p>By default, the <code>EnterpriseCacheSessionDAO</code> asks the 
<code>CacheManager</code> for a <code>Cache</code> named 
&ldquo;<code>shiro-activeSessionCache</code>&rdquo;. This cache name/region is 
expected to be configured in <code>ehcache.xml</code>, as mentioned above.</p>
+<p>If you want to use a different name instead of this default, you can 
configure that name on the <code>EnterpriseCacheSessionDAO</code>, for 
example:</p>
+<p><strong>Configuring the cache name for Shiro&rsquo;s active session cache 
in shiro.ini</strong>&lt;</p>
+<pre><code class="ini[main]">...
 sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
 sessionDAO.activeSessionsCacheName = myname
 ...
-</pre>
-</div></div>
-
-<p>Just ensure that a corresponding entry in <tt>ehcache.xml</tt> matches that 
name and you've configured <tt>overflowToDisk="true"</tt> and 
<tt>eternal="true"</tt> as mentioned above.</p>
-
-<h4><a name="SessionManagement-CustomSessionIDs"></a>Custom Session IDs</h4>
-
-<p>Shiro's <tt>SessionDAO</tt> implementations use an internal <tt><a 
class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/SessionIdGenerator.html">SessionIdGenerator</a></tt>
 component to generate a new Session ID every time a new session is created.  
The ID is generated, assigned to the newly created <tt>Session</tt> instance, 
and then the <tt>Session</tt> is saved via the <tt>SessionDAO</tt>.</p>
-
-<p>The default <tt>SessionIdGenerator</tt> is a <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/JavaUuidSessionIdGenerator.html">JavaUuidSessionIdGenerator</a></tt>,
 which generates <tt>String</tt> IDs based on Java <tt><a class="external-link" 
href="http://download.oracle.com/javase/6/docs/api/java/util/UUID.html"; 
rel="nofollow">UUIDs</a></tt>.  This implementation is suitable for all 
production environments.</p>
-
-<p>If this does not meet your needs, you can implement the 
<tt>SessionIdGenerator</tt> interface and configure the implementation on 
Shiro's <tt>SessionDAO</tt> instance.  For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring a 
SessionIdGenerator in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<p>Just ensure that a corresponding entry in <code>ehcache.xml</code> matches 
that name and you&rsquo;ve configured 
<code>overflowToDisk=&quot;true&quot;</code> and 
<code>eternal=&quot;true&quot;</code> as mentioned above.</p>
+<a name="SessionManagement-CustomSessionIDs"></a>
+<h4><a href="#custom-session-ids" name="custom-session-ids">Custom Session 
IDs</a></h4>
+<p>Shiro&rsquo;s <code>SessionDAO</code> implementations use an internal <a 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/SessionIdGenerator.html"><code>SessionIdGenerator</code></a>
 component to generate a new Session ID every time a new session is created. 
The ID is generated, assigned to the newly created <code>Session</code> 
instance, and then the <code>Session</code> is saved via the 
<code>SessionDAO</code>.</p>
+<p>The default <code>SessionIdGenerator</code> is a <a 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/JavaUuidSessionIdGenerator.html"><code>JavaUuidSessionIdGenerator</code></a>,
 which generates <code>String</code> IDs based on Java <a 
href="http://download.oracle.com/javase/6/docs/api/java/util/UUID.html";><code>UUIDs</code></a>.
 This implementation is suitable for all production environments.</p>
+<p>If this does not meet your needs, you can implement the 
<code>SessionIdGenerator</code> interface and configure the implementation on 
Shiro&rsquo;s <code>SessionDAO</code> instance. For example, in 
<code>shiro.ini</code>:</p>
+<p><strong>Configuring a SessionIdGenerator in shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 sessionIdGenerator = com.my.session.SessionIdGenerator
 securityManager.sessionManager.sessionDAO.sessionIdGenerator = 
$sessionIdGenerator
-
-</pre>
-</div></div>
-
-<h3><a name="SessionManagement-SessionValidation%26Scheduling"></a>Session 
Validation &amp; Scheduling</h3>
-
-<p>Sessions must be validated so any invalid (expired or stopped) sessions can 
be deleted from the session data store.  This ensures that the data store does 
not fill up over time with sessions that will never be used again.</p>
-
-<p>For performance reasons, <tt>Sessions</tt> are only validated to see if 
they have been stopped or expired at the time they are accessed (i.e. 
<tt>subject.getSession()</tt>).  This means that without additional regular 
periodic validation, <tt>Session</tt> orphans would begin to fill up the 
session data store.  </p>
-
-<p>A common example illustrating orphans is the web browser scenario:  Let's 
say a user logs in to a web application and a session is created to retain data 
(authentication state, shopping cart, etc).  If the user does not log out and 
closes their browser without the application knowing about it, their session is 
essentially just 'lying around' (orphaned) in the session data store.  The 
<tt>SessionManager</tt> has no way of detecting that the user was no longer 
using their browser, and the session is never accessed again (it is 
orphaned).</p>
-
-<p>Session orphans, if they are not regularly purged, will fill up the session 
data store (which would be bad).  So, to prevent orphans from piling up, the 
<tt>SessionManager</tt> implementations support the notion of a <tt><a 
class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/SessionValidationScheduler.html">SessionValidationScheduler</a></tt>.
  A <tt>SessionValidationScheduler</tt> is responsible for validating sessions 
at a periodic rate to ensure they are cleaned up as necessary.</p>
-
-<h4><a name="SessionManagement-DefaultSessionValidationScheduler"></a>Default 
SessionValidationScheduler</h4>
-
-<p>The default <tt>SessionValidationScheduler</tt> usable in all environments 
is the <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/ExecutorServiceSessionValidationScheduler.html">ExecutorServiceSessionValidationScheduler</a></tt>
 which uses a JDK <tt><a class="external-link" 
href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html";
 rel="nofollow">ScheduledExecutorService</a></tt> to control how often the 
validation should occur.</p>
-
-<p>By default, this implementation will perform validation once per hour.  You 
can change the rate at which validation occurs by specifying a <b>new</b> 
instance of <tt>ExecutorServiceSessionValidationScheduler</tt> and specifying a 
different interval (in milliseconds):</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 
1px;"><b>ExecutorServiceSessionValidationScheduler interval in 
shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<a name="SessionManagement-SessionValidation%26Scheduling"></a>
+<h3>Session Validation &amp; Scheduling</h3>
+<p>Sessions must be validated so any invalid (expired or stopped) sessions can 
be deleted from the session data store. This ensures that the data store does 
not fill up over time with sessions that will never be used again.</p>
+<p>For performance reasons, <code>Sessions</code> are only validated to see if 
they have been stopped or expired at the time they are accessed (i.e. 
<code>subject.getSession()</code>). This means that without additional regular 
periodic validation, <code>Session</code> orphans would begin to fill up the 
session data store.</p>
+<p>A common example illustrating orphans is the web browser scenario: 
Let&rsquo;s say a user logs in to a web application and a session is created to 
retain data (authentication state, shopping cart, etc). If the user does not 
log out and closes their browser without the application knowing about it, 
their session is essentially just &lsquo;lying around&rsquo; (orphaned) in the 
session data store. The <code>SessionManager</code> has no way of detecting 
that the user was no longer using their browser, and the session is never 
accessed again (it is orphaned).</p>
+<p>Session orphans, if they are not regularly purged, will fill up the session 
data store (which would be bad). So, to prevent orphans from piling up, the 
<code>SessionManager</code> implementations support the notion of a <a 
href="static/current/apidocs/org/apache/shiro/session/mgt/SessionValidationScheduler.html"><code>SessionValidationScheduler</code></a>.
 A <code>SessionValidationScheduler</code> is responsible for validating 
sessions at a periodic rate to ensure they are cleaned up as necessary.</p>
+<a name="SessionManagement-DefaultSessionValidationScheduler"></a>
+<h4><a href="#default-sessionvalidationscheduler" 
name="default-sessionvalidationscheduler">Default 
SessionValidationScheduler</a></h4>
+<p>The default <code>SessionValidationScheduler</code> usable in all 
environments is the <a 
href="static/current/apidocs/org/apache/shiro/session/mgt/ExecutorServiceSessionValidationScheduler.html"><code>ExecutorServiceSessionValidationScheduler</code></a>
 which uses a JDK <a 
href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html";><code>ScheduledExecutorService</code></a>
 to control how often the validation should occur.</p>
+<p>By default, this implementation will perform validation once per hour. You 
can change the rate at which validation occurs by specifying a 
<strong>new</strong> instance of 
<code>ExecutorServiceSessionValidationScheduler</code> and specifying a 
different interval (in milliseconds):</p>
+<p><strong>ExecutorServiceSessionValidationScheduler interval in 
shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 sessionValidationScheduler = 
org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
 # Default is 3,600,000 millis = 1 hour:
 sessionValidationScheduler.interval = 3600000
 
 securityManager.sessionManager.sessionValidationScheduler = 
$sessionValidationScheduler
-
-</pre>
-</div></div>
-
-<p></p>
-
-<h4><a name="SessionManagement-CustomSessionValidationScheduler"></a>Custom 
SessionValidationScheduler</h4>
-
-<p>If you wish to provide a custom <tt>SessionValidationScheduler</tt> 
implementation, you can specify it as a property of the default 
<tt>SessionManager</tt> instance.  For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Configuring a custom 
SessionValidationScheduler in shiro.ini</b></div><div class="codeContent 
panelContent">
-<pre class="code-java">
-[main]
+</code></pre>
+<a name="SessionManagement-CustomSessionValidationScheduler"></a>
+<h4><a href="#custom-sessionvalidationscheduler" 
name="custom-sessionvalidationscheduler">Custom 
SessionValidationScheduler</a></h4>
+<p>If you wish to provide a custom <code>SessionValidationScheduler</code> 
implementation, you can specify it as a property of the default 
<code>SessionManager</code> instance. For example, in 
<code>shiro.ini</code>:</p>
+<p><strong>Configuring a custom SessionValidationScheduler in 
shiro.ini</strong></p>
+<pre><code class="ini">[main]
 ...
 sessionValidationScheduler = com.foo.my.SessionValidationScheduler
 securityManager.sessionManager.sessionValidationScheduler = 
$sessionValidationScheduler
-
-</pre>
-</div></div>
-
-<h4><a name="SessionManagement-DisablingSessionValidation"></a>Disabling 
Session Validation</h4>
-
-<p>In some cases, you might wish to disable session validation entirely 
because you have set up a process outside of Shiro's control to perform the 
validation for you.  For example, maybe you are using an enterprise Cache and 
rely on the cache's Time To Live setting to automatically expunge old sessions. 
 Or maybe you've set up a cron job to auto-purge a custom data store.  In these 
cases you can turn off session validation scheduling:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Disabling Session Validation 
Scheduling in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
-...
-securityManager.sessionManager.sessionValidationSchedulerEnabled = <span 
class="code-keyword">false</span>
-</pre>
-</div></div>
-
-<p>Sessions will still be validated when they are retrieved from the session 
data store, but this will disable Shiro's periodic validation.</p>
-
-#danger('Enable Session Validation <em>somewhere</em>', 'If you turn off 
Shiro's session validation scheduler, you <em>MUST</em> perform periodic 
session validation via some other mechanism (cron job, etc.).  This is the only 
way to guarantee Session orphans do not fill up the data store.')
-
-<h4><a name="SessionManagement-InvalidSessionDeletion"></a>Invalid Session 
Deletion</h4>
-
-<p>As we've stated above, the purpose of periodic session validation is mainly 
to delete any invalid (expired or stopped) sessions to ensure they do not fill 
up the session data store.</p>
-
-<p>By default, whenever Shiro detects an invalid session, it attempts to 
delete it from the underlying session data store via the 
<tt>SessionDAO.delete(session)</tt> method.  This is good practice for most 
applications to ensure the session data storage space is not exhausted.</p>
-
-<p>However, some applications may not wish for Shiro to automatically delete 
sessions.  For example, if an application has provided a <tt>SessionDAO</tt> 
that backs a queryable data store, perhaps the application team wishes old or 
invalid sessions to be available for a certain period of time.  This would 
allow the team to run queries against the data store to see, for example, how 
many sessions a user has created over the last week, or the average duration of 
a user's sessions, or similar reporting-type queries.</p>
-
-<p>In these scenarios, you can turn off invalid session deletion entirely.  
For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>Disabling Invalid Session 
Deletion in shiro.ini</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-[main]
-...
-securityManager.sessionManager.deleteInvalidSessions = <span 
class="code-keyword">false</span>
-</pre>
-</div></div>
-
-<p>But be careful!  If you turn this off, you are responsible for ensuring 
that your session data store doesn't exhaust its space.  You must delete 
invalid sessions from you data store yourself!</p>
-
-<p>Note also that even if you prevent Shiro from deleting invalid sessions, 
you still should enable session validation somehow - either via Shiro's 
existing validation mechanisms or via a custom mechanism you provide yourself 
(see the above "Disabling Session Validation" section above for more).  The 
validation mechanism will update your session records to reflect the invalid 
state (e.g. when it was invalidated, when it was last accessed, etc), even if 
you will delete them manually yourself at some other time.</p>
-
-<div class="panelMacro"><table class="warningMacro"><colgroup span="1"><col 
span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1" 
valign="top"><img align="middle" 
src="https://cwiki.apache.org/confluence/images/icons/emoticons/forbidden.png"; 
width="16" height="16" alt="" border="0"></td><td colspan="1" rowspan="1">If 
you configure Shiro so it does not delete invalid sessions, you are responsible 
for ensuring that your session data store doesn't exhaust its space.  You must 
delete invalid sessions from you data store yourself!
-
-<p>Also note that disabling session deletion is <b>not</b> the same as 
disabling session validation scheduling.  You should almost always use a 
session validation scheduling mechanism - either one supported by Shiro 
directly or your own.</p></td></tr></table></div>
-
-<h2><a name="SessionManagement-SessionClustering"></a>Session Clustering</h2>
-
-<p>One of the very exciting things about Apache Shiro's session capabilities 
is that you can cluster Subject sessions natively and never need to worry again 
about how to cluster sessions based on your container environment.  That is, if 
you use Shiro's native sessions and configure a session cluster, you can, say, 
deploy to Jetty or Tomcat in development, JBoss or Geronimo in production, or 
any other environment - all the while never worrying about 
container/environment-specific clustering setup or configuration.  Configure 
session clustering once in Shiro and it works no matter your deployment 
environment.</p>
-
+</code></pre>
+<a name="SessionManagement-DisablingSessionValidation"></a>
+<h4><a href="#disabling-session-validation" 
name="disabling-session-validation">Disabling Session Validation</a></h4>
+<p>In some cases, you might wish to disable session validation entirely 
because you have set up a process outside of Shiro&rsquo;s control to perform 
the validation for you. For example, maybe you are using an enterprise Cache 
and rely on the cache&rsquo;s Time To Live setting to automatically expunge old 
sessions. Or maybe you&rsquo;ve set up a cron job to auto-purge a custom data 
store. In these cases you can turn off session validation scheduling:</p>
+<p><strong>Disabling Session Validation Scheduling in shiro.ini</strong></p>
+<pre><code class="ini">[main]
+...
+securityManager.sessionManager.sessionValidationSchedulerEnabled = false
+</code></pre>
+<p>Sessions will still be validated when they are retrieved from the session 
data store, but this will disable Shiro&rsquo;s periodic validation.</p>
+<div class="panelMacro">
+    <table class="warningMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-exclamation-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Enable Session Validation <i>somewhere</i></b>
+                <br clear="none">
+                If you turn off Shiro's session validation scheduler, you 
<i>MUST</i> perform periodic session validation via some other mechanism (cron 
job, etc.). This is the only way to guarantee Session orphans do not fill up 
the data store.
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-InvalidSessionDeletion"></a>
+<h4><a href="#invalid-session-deletion" 
name="invalid-session-deletion">Invalid Session Deletion</a></h4>
+<p>As we&rsquo;ve stated above, the purpose of periodic session validation is 
mainly to delete any invalid (expired or stopped) sessions to ensure they do 
not fill up the session data store.</p>
+<p>By default, whenever Shiro detects an invalid session, it attempts to 
delete it from the underlying session data store via the 
<code>SessionDAO.delete(session)</code> method. This is good practice for most 
applications to ensure the session data storage space is not exhausted.</p>
+<p>However, some applications may not wish for Shiro to automatically delete 
sessions. For example, if an application has provided a <code>SessionDAO</code> 
that backs a queryable data store, perhaps the application team wishes old or 
invalid sessions to be available for a certain period of time. This would allow 
the team to run queries against the data store to see, for example, how many 
sessions a user has created over the last week, or the average duration of a 
user&rsquo;s sessions, or similar reporting-type queries.</p>
+<p>In these scenarios, you can turn off invalid session deletion entirely. For 
example, in <code>shiro.ini</code>:</p>
+<p><strong>Disabling Invalid Session Deletion in shiro.ini</strong></p>
+<pre><code class="ini">[main]
+...
+securityManager.sessionManager.deleteInvalidSessions = false
+</code></pre>
+<p>But be careful! If you turn this off, you are responsible for ensuring that 
your session data store doesn&rsquo;t exhaust its space. You must delete 
invalid sessions from you data store yourself!</p>
+<p>Note also that even if you prevent Shiro from deleting invalid sessions, 
you still should enable session validation somehow - either via Shiro&rsquo;s 
existing validation mechanisms or via a custom mechanism you provide yourself 
(see the above &ldquo;Disabling Session Validation&rdquo; section above for 
more). The validation mechanism will update your session records to reflect the 
invalid state (e.g. when it was invalidated, when it was last accessed, etc), 
even if you will delete them manually yourself at some other time.</p>
+<div class="panelMacro">
+<div class="panelMacro">
+    <table class="warningMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-exclamation-circle"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Warning</b>
+                <br clear="none">
+                If you configure Shiro so it does not delete invalid sessions, 
you are responsible for ensuring that your session data store doesn't exhaust 
its space. You must delete invalid sessions from you data store yourself!
+<p>Also note that disabling session deletion is <strong>not</strong> the same 
as disabling session validation scheduling. You should almost always use a 
session validation scheduling mechanism - either one supported by Shiro 
directly or your own.</p>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-SessionClustering"></a>
+<h2><a href="#session-clustering" name="session-clustering">Session 
Clustering</a></h2>
+<p>One of the very exciting things about Apache Shiro&rsquo;s session 
capabilities is that you can cluster Subject sessions natively and never need 
to worry again about how to cluster sessions based on your container 
environment. That is, if you use Shiro&rsquo;s native sessions and configure a 
session cluster, you can, say, deploy to Jetty or Tomcat in development, JBoss 
or Geronimo in production, or any other environment - all the while never 
worrying about container/environment-specific clustering setup or 
configuration. Configure session clustering once in Shiro and it works no 
matter your deployment environment.</p>
 <p>So how does it work?</p>
-
-<p>Because of Shiro's POJO-based N-tiered architecture, enabling Session 
clustering is as simple as enabling a clustering mechanism at the Session 
persistence level.  That is, if you configure a cluster-capable <tt><a 
href="#SessionManagement-sessionstorage">SessionDAO</a></tt>, the DAO can 
interact with a clustering mechanism and Shiro's <tt>SessionManager</tt> never 
needs to know about clustering concerns.</p>
-
-<p><b>Distributed Caches</b></p>
-
-<p>Distributed Caches such as <a class="external-link" 
href="http://www.ehcache.org/documentation/2.7/configuration/distributed-cache-configuration.html";
 rel="nofollow">Ehcache+TerraCotta</a>, <a class="external-link" 
href="http://www.gigaspaces.com/"; rel="nofollow">GigaSpaces</a> <a 
class="external-link" 
href="http://www.oracle.com/technetwork/middleware/coherence/overview/index.html";
 rel="nofollow">Oracle Coherence</a>, and <a class="external-link" 
href="http://memcached.org/"; rel="nofollow">Memcached</a> (and many others) 
already solve the distributed-data-at-the-persistence-level problem.  Therefore 
enabling Session clustering in Shiro is as simple as configuring Shiro to use a 
distributed cache.</p>
-
+<p>Because of Shiro&rsquo;s POJO-based N-tiered architecture, enabling Session 
clustering is as simple as enabling a clustering mechanism at the Session 
persistence level. That is, if you configure a cluster-capable <a 
href="#SessionManagement-sessionstorage"><code>SessionDAO</code></a>, the DAO 
can interact with a clustering mechanism and Shiro&rsquo;s 
<code>SessionManager</code> never needs to know about clustering concerns.</p>
+<p><strong>Distributed Caches</strong></p>
+<p>Distributed Caches such as <a 
href="http://www.ehcache.org/documentation/2.7/configuration/distributed-cache-configuration.html";>Ehcache+TerraCotta</a>,
 <a href="http://www.gigaspaces.com/";>GigaSpaces</a> <a 
href="http://www.oracle.com/technetwork/middleware/coherence/overview/index.html";>Oracle
 Coherence</a>, and <a href="http://memcached.org/";>Memcached</a> (and many 
others) already solve the distributed-data-at-the-persistence-level problem. 
Therefore enabling Session clustering in Shiro is as simple as configuring 
Shiro to use a distributed cache.</p>
 <p>This gives you the flexibility of choosing the exact clustering mechanism 
that is suitable for <em>your</em> environment.</p>
-
-#warning('Cache Memory', 'Note that when enabling a distributed/enterprise 
cache to be your session clustering data store, one of the following two cases 
must be true:
-<ul><li>The distributed cache has enough cluster-wide memory to retain 
<em>all</em> active/current sessions</li><li>If the distributed cache does not 
have enough cluster-wide memory to retain all active sessions, it must support 
disk overflow so sessions are not lost.<br clear="none">
-Failure for the cache to support either of the two cases will result in 
sessions being randomly lost, which would likely be frustrating to 
end-users.</li></ul>
-')
-
-<h3><a 
name="SessionManagement-%7B%7BEnterpriseCacheSessionDAO%7D%7D"></a><tt>EnterpriseCacheSessionDAO</tt></h3>
-
-<p>As you might expect, Shiro already provides a <tt>SessionDAO</tt> 
implementation that will persist data to an enterprise/distributed Cache.  The 
<a class="external-link" 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/EnterpriseCacheSessionDAO.html">EnterpriseCacheSessionDAO</a>
 expects a Shiro <tt>Cache</tt> or <tt>CacheManager</tt> to be configured on it 
so it can leverage the caching mechanism.</p>
-
-<p>For example, in <tt>shiro.ini</tt>:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-java">
-#This implementation would use your preferred distributed caching product's 
APIs:
+<div class="panelMacro">
+    <table class="noteMacro">
+        <colgroup span="1">
+            <col span="1" width="24">
+            <col span="1">
+        </colgroup>
+        <tbody>
+        <tr>
+            <td colspan="1" rowspan="1" valign="top">
+                <i class="fa fa-warning"></i>
+            </td>
+
+            <td colspan="1" rowspan="1">
+                <b>Cache Memory</b>
+                <br clear="none">
+                Note that when enabling a distributed/enterprise cache to be 
your session clustering data store, one of the following two cases must be true:
+<ul><li>The distributed cache has enough cluster-wide memory to retain _all_ 
active/current sessions</li>
+<li>If the distributed cache does not have enough cluster-wide memory to 
retain all active sessions, it must support disk overflow so sessions are not 
lost.</li></ul>
+Failure for the cache to support either of the two cases will result in 
sessions being randomly lost, which would likely be frustrating to end-users.
+
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<a name="SessionManagement-%7B%7BEnterpriseCacheSessionDAO%7D%7D"></a>
+<h3><a href="#enterprisecachesessiondao" 
name="enterprisecachesessiondao">EnterpriseCacheSessionDAO</a></h3>
+<p>As you might expect, Shiro already provides a <code>SessionDAO</code> 
implementation that will persist data to an enterprise/distributed Cache. The 
<a 
href="static/current/apidocs/org/apache/shiro/session/mgt/eis/EnterpriseCacheSessionDAO.html">EnterpriseCacheSessionDAO</a>
 expects a Shiro <code>Cache</code> or <code>CacheManager</code> to be 
configured on it so it can leverage the caching mechanism.</p>
+<p>For example, in <code>shiro.ini</code>:</p>
+<pre><code class="ini">#This implementation would use your preferred 
distributed caching product&#39;s APIs:
 activeSessionsCache = my.org.apache.shiro.cache.CacheImplementation
 
 sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
 sessionDAO.activeSessionsCache = $activeSessionsCache
 
 securityManager.sessionManager.sessionDAO = $sessionDAO
-</pre>
-</div></div> 
-
-<p>Although you could inject a <tt>Cache</tt> instance directly to the 
<tt>SessionDAO</tt> as shown above, it is usually far more common to configure 
a general <tt>CacheManager</tt> to use for all of Shiro's caching needs 
(sessions as well as authentication and authorization data).  In this case, 
instead of configuring a <tt>Cache</tt> instance directly, you would tell the 
<tt>EnterpriseCacheSessionDAO</tt> the name of the cache in the 
<tt>CacheManager</tt> that should be used for storing active sessions.</p>
-
+</code></pre>
+<p>Although you could inject a <code>Cache</code> instance directly to the 
<code>SessionDAO</code> as shown above, it is usually far more common to 
configure a general <code>CacheManager</code> to use for all of Shiro&rsquo;s 
caching needs (sessions as well as authentication and authorization data). In 
this case, instead of configuring a <code>Cache</code> instance directly, you 
would tell the <code>EnterpriseCacheSessionDAO</code> the name of the cache in 
the <code>CacheManager</code> that should be used for storing active 
sessions.</p>
 <p>For example:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeContent 
panelContent">
-<pre class="code-java">
-# This implementation would use your caching product's APIs:
+<pre><code class="ini"># This implementation would use your caching 
product&#39;s APIs:
 cacheManager = my.org.apache.shiro.cache.CacheManagerImplementation
 
 # Now configure the EnterpriseCacheSessionDAO and tell it what
 # cache in the CacheManager should be used to store active sessions:
 sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
-# This is the <span class="code-keyword">default</span> value.  Change it 
<span class="code-keyword">if</span> your CacheManager configured a different 
name:
+# This is the default value.  Change it if your CacheManager configured a 
different name:
 sessionDAO.activeSessionsCacheName = shiro-activeSessionsCache
-# Now have the <span class="code-keyword">native</span> SessionManager use 
that DAO:
+# Now have the native SessionManager use that DAO:
 securityManager.sessionManager.sessionDAO = $sessionDAO
 
-# Configure the above CacheManager on Shiro's <span 
class="code-object">SecurityManager</span>
-# to use it <span class="code-keyword">for</span> all of Shiro's caching needs:
+# Configure the above CacheManager on Shiro&#39;s SecurityManager
+# to use it for all of Shiro&#39;s caching needs:
 securityManager.cacheManager = $cacheManager
-</pre>
-</div></div>
-
-<p>But there's something a bit strange about the above configuration.  Did you 
notice it?</p>
-
-<p>The interesting thing about this config is that nowhere in the config did 
we actually tell the <tt>sessionDAO</tt> instance to use a <tt>Cache</tt> or 
<tt>CacheManager</tt>!  So how does the <tt>sessionDAO</tt> use the distributed 
cache?</p>
-
-<p>When Shiro initializes the <tt>SecurityManager</tt>, it will check to see 
if the <tt>SessionDAO</tt> implements the <tt><a class="external-link" 
href="static/current/apidocs/org/apache/shiro/cache/CacheManagerAware.html">CacheManagerAware</a></tt>
 interface. If it does, it will automatically be supplied with any available 
globally configured <tt>CacheManager</tt>.</p>
-
-<p>So when Shiro evaluates the <tt>securityManager.cacheManager = 
$cacheManager</tt> line, it will discover that the 
<tt>EnterpriseCacheSessionDAO</tt> implements the <tt>CacheManagerAware</tt> 
interface and call the <tt>setCacheManager</tt> method with your configured 
<tt>CacheManager</tt> as the method argument.  </p>
-
-<p>Then at runtime, when the <tt>EnterpriseCacheSessionDAO</tt> needs the 
<tt>activeSessionsCache</tt> it will ask the <tt>CacheManager</tt> instance to 
return it it, using the <tt>activeSessionsCacheName</tt> as the lookup key to 
get a <tt>Cache</tt> instance.  That <tt>Cache</tt> instance (backed by your 
distributed/enterprise caching product's API) will be used to store and 
retrieve sessions for all of the <tt>SessionDAO</tt> CRUD operations.</p>
-
-<h3><a name="SessionManagement-EhcacheTerracotta"></a>Ehcache + Terracotta</h3>
-
-<p>One such distributed caching solution that people have had success with 
while using Shiro is the Ehcache + Terracotta pairing.  See the Ehcache-hosted 
<a class="external-link" 
href="http://www.ehcache.org/documentation/get-started/about-distributed-cache"; 
rel="nofollow">Distributed Caching With Terracotta</a> documentation for full 
details of how to enable distributed caching with Ehcache.</p>
-
-<p>Once you've got Terracotta clustering working with Ehcache, the 
Shiro-specific parts are very simple.  Read and follow the <a 
href="#SessionManagement-ehcachesessiondao">Ehcache SessionDAO</a> 
documentation, but we'll need to make a few changes</p>
-
-<p>The Ehcache Session Cache Configuration <a 
href="#SessionManagement-ehcachesessioncacheconfiguration">referenced 
previously</a> will not work - a Terracotta-specific configuration is needed.  
Here is an example configuration that has been tested to work correctly.  Save 
its contents in a file and save it in an <tt>ehcache.xml</tt> file:</p>
-
-<div class="code panel" style="border-width: 1px;"><div class="codeHeader 
panelHeader" style="border-bottom-width: 1px;"><b>TerraCotta Session 
Clustering</b></div><div class="codeContent panelContent">
-<pre class="code-xml">
-<span class="code-tag">&lt;ehcache&gt;</span>
-    <span class="code-tag">&lt;terracottaConfig url=<span 
class="code-quote">"localhost:9510"</span>/&gt;</span>
-    <span class="code-tag">&lt;diskStore path=<span 
class="code-quote">"java.io.tmpdir/shiro-ehcache"</span>/&gt;</span>
+</code></pre>
+<p>But there&rsquo;s something a bit strange about the above configuration. 
Did you notice it?</p>
+<p>The interesting thing about this config is that nowhere in the config did 
we actually tell the <code>sessionDAO</code> instance to use a 
<code>Cache</code> or <code>CacheManager</code>! So how does the 
<code>sessionDAO</code> use the distributed cache?</p>
+<p>When Shiro initializes the <code>SecurityManager</code>, it will check to 
see if the <code>SessionDAO</code> implements the <a 
href="static/current/apidocs/org/apache/shiro/cache/CacheManagerAware.html"><code>CacheManagerAware</code></a>
 interface. If it does, it will automatically be supplied with any available 
globally configured <code>CacheManager</code>.</p>
+<p>So when Shiro evaluates the <code>securityManager.cacheManager = 
$cacheManager</code> line, it will discover that the 
<code>EnterpriseCacheSessionDAO</code> implements the 
<code>CacheManagerAware</code> interface and call the 
<code>setCacheManager</code> method with your configured 
<code>CacheManager</code> as the method argument.</p>
+<p>Then at runtime, when the <code>EnterpriseCacheSessionDAO</code> needs the 
<code>activeSessionsCache</code> it will ask the <code>CacheManager</code> 
instance to return it it, using the <code>activeSessionsCacheName</code> as the 
lookup key to get a <code>Cache</code> instance. That <code>Cache</code> 
instance (backed by your distributed/enterprise caching product&rsquo;s API) 
will be used to store and retrieve sessions for all of the 
<code>SessionDAO</code> CRUD operations.</p>
+<a name="SessionManagement-EhcacheTerracotta"></a>
+<h3><a href="#ehcache-terracotta" name="ehcache-terracotta">Ehcache + 
Terracotta</a></h3>

[... 357 lines stripped ...]


Reply via email to