Hi Garoad,

Yes you're right - this is very possible and there are more than a few
that do it already, but the documentation in lower-level Session
Management customization is lacking at the moment.  However, the
solution is simple enough (I elaborate quite a bit below, so it looks
more cumbersome than it really is - but it's really pretty easy):

1.  Turn on native session management

If using a web.xml configured ShiroFilter, a DefaultWebSecurityManager
is enabled by default, and that in turn defaults to piggybacking the
servlet-container Sessions and not using Shiro's native session
management.  In order to control Session persistence yourself, you
need to ensure that you're running a 'native' SessionManager.  E.g. in
INI:

[main]
...
securityManager.sessionMode = native

This is only necessary if configuring Shiro as a ShiroFilter.
Otherwise, native sessions are enabled by default.

2.  Implement the org.apache.shiro.session.mgt.eis.SessionDAO
interface to talk to your RDBMS.  If your RDBMS interaction API of
choice implements caching behavior already (e.g. Hibernate w/ it's 1st
and 2nd-level cache), you can implement the interface directly.

However, if it your RDBS API does not perform caching directly (e.g.
using just raw JDBC), it is pretty much expected that you will
subclass the org.apache.shiro.session.mgt.eis.CachingSessionDAO and
then configure a CacheManager in Shiro:

This is because Shiro does not currently integrate with any
Transaction Management APIs and so it can't have a 'thread local
cache' of a Session instance bound to a Transaction context.  So that
means _every_ session operation will hit your datasource unless you
employ a cache.  Even if you only use the simple out-of-the-box
Ehcache support, this is better than nothing.  This way the cache will
alleviate constant hits on your RDBMS (which can easily occur 10 or
more times during an average request).

Again, this caching concern only exists if your RDBMS API of choice
does not already support caching.

3.  Inject your session DAO into the native SessionManager and
configure a CacheManager if necessary according to #2 above.  For
example, in INI:

sessionDAO = com.mycompany.shiro.JdbcSessionDAOThatSubclassesCachingSessionDAO
...

# the following call is only necessary in a web-configured ShiroFilter
(otherwise
# a native session manager is already enabled):
securityManager.sessionMode = native

# now that we're using a native SessionManager (wrapped by the
# SecurityManager instance), inject the sessionDAO:
securityManager.sessionManager.sessionDAO = $sessionDAO

#inject your cacheManager:
securityManager.cacheManager = $myCacheManager

I hope that helps!

As to your 'DB is the central place' for sessions comment, I would
really recommend that you look at a distributed cache - even Ehcache's
networked version or Memcache at a minimum.  They are designed
specifically for transient data that needs to be accessible locally as
much as possible, but available on other nodes if necessary.  They are
essentially a poster child for session clustering and there is almost
no better solution.  You will have _much_ better performance from a
distributed cache managing sessions than you will an RDBMS (this is my
bread and butter for my 'day job' :))

I would only save to an RDBMS if you needed to do any kind of querying
or reporting on sessions data, but I would still always front that
RDBMS with a clustered cache for to performance.  Distributed caches
are free and/or cheap (enought) these days with options like Memcache,
Ehcache and Terracotta - I highly recommend going that route if you
need clustered sessions.

Anyway, that's just a recommendation - you know your environment,
project limitations and deployment environment better than I ever
could.  I just wanted to put that out there as food for thought, and
to potentially help anyone else pondering a solution if they have
similar requirements.

Cheers,

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com

On Sun, Oct 17, 2010 at 1:52 PM, Garoad <ehamm...@gmail.com> wrote:
>
> The documentation in this area seems to be missing - where do we start (and
> can we?) to have sessions stored in a database rather than an enterprise
> cache (like Terracotta, Gigaspaces, etc - we don't have any of these
> available).  The diagram here seems to indicate that this is possible:
> http://shiro.apache.org/architecture.html
>
> But I can't find anything that seems relevant in the API docs.  Here's the
> desired goal:
>
> -Authentication by LDAP (Active Directory)
> -Authorization on each request by permissions stored for each user within
> Oracle
> -Clustered application server environment (4 different servers, 4 different
> JVMs, etc etc etc... this is why we need some way to 'share' sessions across
> servers and I'm hoping the DB is the central place for this)
> -Flex client talking to Java via Granite Data Services
>
> It's a little difficult figuring out where to start and what the game plan
> should be for getting this set up. Thanks,
> --
> View this message in context: 
> http://shiro-user.582556.n2.nabble.com/Storing-sessins-in-an-RDBMS-instead-of-an-enterprise-cache-tp5645213p5645213.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>

Reply via email to