I finally got around to testing this workaround, and it didn't work.
Here's what I'm using:
# pull in vonage centralized authentication:
realmA = com.vonage.auth.VonageAuthenticationRealm
securityManager = org.apache.shiro.web.DefaultWebSecurityManager
sessionManager =
org.apache.shiro.web.session.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionMode = native
#cacheManager = org.apache.shiro.cache.DefaultCacheManager
sessionDAO = org.apache.shiro.session.mgt.eis.MemorySessionDAO
securityManager.sessionDAO = $sessionDAO
securityManager.realm = $realmA
cacheManager =
com.vonage.auth.VonageDistributedSessionCacheManager
securityManager.cacheManager = $cacheManager
sessionDAO.cacheManager = $cacheManager
realmA.cacheManager = $cacheManager
I'm seeing 4 calls to AuthorizingRealm.setAuthorizationCache(). First, it's
passed a SoftHashMapCache, then twice it's called with my
VonageDistributedSessionCache, and then one final call with a SoftHashMapCache
again.
Oddly, I noticed that every time AuthorizingRealm.setAuthorizationCache() is
called, the current this.authorizationCache is null. It's getting nulled out
by calls to afterCacheManagerSet().
Andy
> -----Original Message-----
> From: Andy Tripp [mailto:[email protected]]
> Sent: Thursday, September 03, 2009 3:43 PM
> To: [email protected]
> Subject: RE: need help plugging in my own session cache
>
> I created a Jira issue: https://issues.apache.org/jira/browse/SHIRO-95
>
> I'll try this workaround now.
> Thanks, Les!
>
> Andy
>
> > -----Original Message-----
> > From: [email protected] [mailto:[email protected]] On
> > Behalf Of Les Hazlewood
> > Sent: Wednesday, September 02, 2009 3:03 PM
> > To: [email protected]
> > Subject: Re: need help plugging in my own session cache
> >
> > This is an order of operations bug. Please open a Jira issue so we
> > can fix it.
> >
> > In the mean time, setting the sessionDAO on the securityManager
> > _before_ setting the cache manager should do the trick.
> >
> > Here is a configuration that is working for me:
> >
> > <filter>
> > <filter-name>ShiroFilter</filter-name>
> > <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-
> > class>
> > <init-param>
> > <param-name>config</param-name>
> > <param-value>
> > [main]
> >
> > securityManager.sessionMode = native
> >
> > sessionDAO =
> > org.apache.shiro.session.mgt.eis.MemorySessionDAO
> > securityManager.sessionDAO = $sessionDAO
> >
> > cacheManager = TestCacheManager
> > securityManager.cacheManager = $cacheManager
> >
> > demoRealm = org.apache.shiro.realm.text.PropertiesRealm
> > securityManager.realm = $demoRealm
> >
> > # add [filters] and [urls] sections here as necessary
> >
> > </param-value>
> > </init-param>
> > </filter>
> >
> > On Wed, Sep 2, 2009 at 1:16 PM, Les Hazlewood<[email protected]>
> > wrote:
> > > Hi Andy,
> > >
> > > There is definitely a bug in the configuration stuff - I'm looking in
> > > to it to find out what may be wrong. I'll keep you posted.
> > >
> > > - Les
> > >
> > > On Tue, Sep 1, 2009 at 2:39 PM, Les Hazlewood<[email protected]>
> > wrote:
> > >> Hi Andy,
> > >>
> > >> I'll have to give this a look sometime later tonight or tomorrow when
> > >> I have time - I'm kinda slammed today. But don't worry - we'll get
> it
> > >> working!
> > >>
> > >> Best,
> > >>
> > >> Les
> > >>
> > >> On Tue, Sep 1, 2009 at 11:58 AM, Andy Tripp<[email protected]>
> > wrote:
> > >>> I made some progress on this issue.
> > >>>
> > >>>
> > >>>
> > >>> I added tracing to AuthorizingRealm.setAuthorizationCache(). I see
> > that it's
> > >>> first being correctly called to set the cache to my "custom"
> > >>> VonageDistributedSessionCache that I specified in my ShiroFilter.
> But
> > then,
> > >>> I see that it's being called a second time, and getting *reset* to
> > some
> > >>> instance of SoftHashMapCache.
> > >>>
> > >>>
> > >>>
> > >>> The stack trace of that 2nd call is below. So the issue is "where in
> > that
> > >>> stack trace is some code having the audacity to do something that
> > results in
> > >>> a call to AuthorizingRealm.setAuthorizationCache(), which replaces
> the
> > >>> user-specified cache with the default of a SoftHashMapCache?
> > >>>
> > >>>
> > >>>
> > >>> My (uneducated) guess is that the culprit is the
> > createSecurityManager()
> > >>> call in IniConfiguration.processIni(). Why would we want to create a
> > >>> security manager when in the middle of processing configuration
> data?
> > >>>
> > >>>
> > >>>
> > >>> In any case, I think the use case is simple: trying to specify your
> > own
> > >>> CacheManager doesn't work. Here's my ShiroFilter:
> > >>>
> > >>> # pull in vonage centralized authentication:
> > >>>
> > >>> realmA = com.vonage.auth.VonageAuthenticationRealm
> > >>>
> > >>> securityManager =
> > >>> org.apache.shiro.web.DefaultWebSecurityManager
> > >>>
> > >>> sessionManager =
> > >>> org.apache.shiro.web.session.DefaultWebSessionManager
> > >>>
> > >>> securityManager.sessionManager = $sessionManager
> > >>>
> > >>> securityManager.sessionMode = native
> > >>>
> > >>> #cacheManager =
> > org.apache.shiro.cache.DefaultCacheManager
> > >>>
> > >>>
> > >>>
> > >>> cacheManager =
> > >>> com.vonage.auth.VonageDistributedSessionCacheManager
> > >>>
> > >>> securityManager.cacheManager = $cacheManager
> > >>>
> > >>>
> > >>>
> > >>> sessionDAO =
> > >>> org.apache.shiro.session.mgt.eis.MemorySessionDAO
> > >>>
> > >>> #sessionDAO.cacheManager = $cacheManager
> > >>>
> > >>> securityManager.sessionDAO = $sessionDAO
> > >>>
> > >>> securityManager.realm = $realmA
> > >>>
> > >>>
> > >>>
> > >>> And here's the stack trace I talked about:
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> java.lang.Exception: Stack trace
> > >>>
> > >>> at java.lang.Thread.dumpStack(Thread.java:1206)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.realm.AuthorizingRealm.setAuthorizationCache(AuthorizingR
> > ealm.java:109)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.realm.AuthorizingRealm.initAuthorizationCache(Authorizing
> > Realm.java:199)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.realm.AuthorizingRealm.afterCacheManagerSet(AuthorizingRe
> > alm.java:166)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.realm.CachingRealm.setCacheManager(CachingRealm.java:73)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.mgt.RealmSecurityManager.applyCacheManagerToRealms(RealmS
> > ecurityManager.java:116)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.mgt.RealmSecurityManager.afterRealmsSet(RealmSecurityMana
> > ger.java:86)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.mgt.AuthenticatingSecurityManager.afterRealmsSet(Authenti
> > catingSecurityManager.java:178)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.mgt.AuthorizingSecurityManager.afterRealmsSet(Authorizing
> > SecurityManager.java:129)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.mgt.RealmSecurityManager.setRealms(RealmSecurityManager.j
> > ava:82)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.IniConfiguration.createSecurityManagerForSection(I
> > niConfiguration.java:242)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.IniConfiguration.createSecurityManager(IniConfigur
> > ation.java:188)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.IniConfiguration.processIni(IniConfiguration.java:
> > 172)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.IniConfiguration.process(IniConfiguration.java:161
> > )
> > >>>
> > >>> at
> > >>>
> > org.apache.shiro.config.IniConfiguration.load(IniConfiguration.java:127)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.TextConfiguration.loadTextConfig(TextConfiguration
> > .java:70)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.config.TextConfiguration.init(TextConfiguration.java:86)
> > >>>
> > >>> at
> > >>>
> > org.apache.shiro.config.IniConfiguration.init(IniConfiguration.java:114)
> > >>>
> > >>> at
> > org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:47)
> > >>>
> > >>> at
> > org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:41)
> > >>>
> > >>> at
> > >>>
> > org.apache.shiro.web.servlet.ShiroFilter.configure(ShiroFilter.java:322)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.ShiroFilter.onFilterConfigSet(ShiroFilter.jav
> > a:269)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter.init(OncePerRequestFilte
> > r.java:140)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilt
> > erConfig.java:221)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationF
> > ilterConfig.java:302)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterC
> > onfig.java:78)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:
> > 3635)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardContext.start(StandardContext.java:4222)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java
> > :760)
> > >>>
> > >>> at
> > >>>
> > org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:927
> > )
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:8
> > 90)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
> > >>>
> > >>> at
> > org.apache.catalina.startup.HostConfig.start(HostConfig.java:1150)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupp
> > ort.java:120)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022)
> > >>>
> > >>> at
> > org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
> > >>>
> > >>> at
> > >>>
> > org.apache.catalina.core.StandardService.start(StandardService.java:448)
> > >>>
> > >>> at
> > >>>
> org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
> > >>>
> > >>> at
> org.apache.catalina.startup.Catalina.start(Catalina.java:552)
> > >>>
> > >>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > >>>
> > >>> at
> > >>>
> >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
> > 39)
> > >>>
> > >>> at
> > >>>
> >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorIm
> > pl.java:25)
> > >>>
> > >>> at java.lang.reflect.Method.invoke(Method.java:597)
> > >>>
> > >>> at
> > org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
> > >>>
> > >>> at
> > org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)
> > >>>
> > >>>
> > >>>
> > >>> Andy
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> ________________________________
> > >>>
> > >>> From: Andy Tripp [mailto:[email protected]]
> > >>> Sent: Monday, August 31, 2009 10:25 AM
> > >>> To: [email protected]
> > >>> Subject: RE: need help plugging in my own session cache
> > >>>
> > >>>
> > >>>
> > >>> I need to get this working, and I'm happy to track it down myself,
> but
> > I
> > >>> need some starting direction.
> > >>>
> > >>>
> > >>>
> > >>> If I want to use my own cache for storing session data, I know I
> > should
> > >>> write my own CacheManager and a class that implements Cache. But
> which
> > class
> > >>> do I tell to use my own cache? Is it SessionDAO, securityManager, or
> > my own
> > >>> Realm (in my case a subclass of JDBCRealm)? All three have a
> > cacheManager
> > >>> property.
> > >>>
> > >>>
> > >>>
> > >>> Thanks,
> > >>>
> > >>> Andy
> > >>>
> > >>>
> > >>>
> > >>> ________________________________
> > >>>
> > >>> From: Andy Tripp [mailto:[email protected]]
> > >>> Sent: Friday, August 28, 2009 2:56 PM
> > >>> To: [email protected]
> > >>> Subject: need help plugging in my own session cache
> > >>>
> > >>>
> > >>>
> > >>> Hi again,
> > >>>
> > >>>
> > >>>
> > >>> I'm having trouble with specifying my own Cache.
> > >>>
> > >>> I've specified my own CacheManager and Cache classes in my
> > ShiroFilter:
> > >>>
> > >>>
> > >>>
> > >>> realmA = com.vonage.auth.VonageAuthenticationRealm
> > >>>
> > >>> securityManager =
> > >>> org.apache.shiro.web.DefaultWebSecurityManager
> > >>>
> > >>> sessionManager =
> > >>> org.apache.shiro.web.session.DefaultWebSessionManager
> > >>>
> > >>> securityManager.sessionManager = $sessionManager
> > >>>
> > >>> securityManager.sessionMode = native
> > >>>
> > >>> #cacheManager =
> > org.apache.shiro.cache.DefaultCacheManager
> > >>>
> > >>> cacheManager =
> > >>> com.vonage.auth.VonageDistributedSessionCacheManager
> > >>>
> > >>> sessionDAO =
> > >>> org.apache.shiro.session.mgt.eis.MemorySessionDAO
> > >>>
> > >>> sessionDAO.cacheManager = $cacheManager
> > >>>
> > >>> securityManager.sessionDAO = $sessionDAO
> > >>>
> > >>> securityManager.cacheManager = $cacheManager
> > >>>
> > >>> securityManager.realm = $realmA
> > >>>
> > >>> realmA.cacheManager = $cacheManager
> > >>>
> > >>>
> > >>>
> > >>> My VonageDistributedSessionCacheManager class simply returns an
> > instance of
> > >>> my VonageDistributedSessionCache class, which implements the Cache
> > >>> interface.
> > >>>
> > >>>
> > >>>
> > >>> The problem is that the various methods in my
> > VonageDistributedSessionCache
> > >>> class (get(), put(), etc) are never being called. By adding tracing,
> I
> > can
> > >>> confirm that my VonageDistributedSessionCache constructor is being
> > called
> > >>> from AuthorizationRealm.initAuthorizationCache(). But when I login
> to
> > my
> > >>> servlet, my get() and put() methods are never called. On my first
> > login
> > >>> attempt to get to my servlet, I have no session and so I'm
> challenged
> > for
> > >>> username/password. Then on a second attempt, it lets me through. So
> > >>> somewhere Shiro is caching my sessionid, but I don't know where. All
> I
> > know
> > >>> is that it's not using the Cache that I told it to :) In fact, I
> told
> > it 3
> > >>> times ($cacheManager is mentioned 3 times above)!
> > >>>
> > >>>
> > >>>
> > >>> So where is it in Shiro that checks the session cache? I see that
> > >>> AuthorizingRealm.initAuthorizationCache() does create an instance of
> > my
> > >>> VonageDistributedSessionCache class, and calls
> setAuthorizationCache()
> > to
> > >>> store it. But I don't see any calls to the corresponding
> > >>> getAuthorizationCache() to actually use it.
> > >>>
> > >>>
> > >>>
> > >>> I'm not sure if this helps or not, but below is a stack trace from
> my
> > >>> servlet. Somewhere along this chain of calls, somebody should have
> > called
> > >>> AuthorizingRealm.getAuthorizationCache() but didn't.
> > >>>
> > >>>
> > >>>
> > >>> Thanks,
> > >>>
> > >>> Andy
> > >>>
> > >>> --------------------------------------------------------------------
> --
> > ------------------------
> > >>>
> > >>> at java.lang.Thread.dumpStack(Thread.java:1206)
> > >>>
> > >>> at
> > >>>
> com.vonage.authenticatorTest.TestServlet1.doGet(TestServlet1.java:15)
> > >>>
> > >>> at
> javax.servlet.http.HttpServlet.service(HttpServlet.java:627)
> > >>>
> > >>> at
> javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicati
> > onFilterChain.java:269)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilter
> > Chain.java:188)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChai
> > n.java:58)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:1
> > 07)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.ja
> > va:137)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestF
> > ilter.java:190)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChai
> > n.java:63)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.ShiroFilter.executeChain(ShiroFilter.java:648
> > )
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java
> > :588)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestF
> > ilter.java:190)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applicati
> > onFilterChain.java:215)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilter
> > Chain.java:188)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.
> > java:213)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.
> > java:172)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:1
> > 27)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:1
> > 17)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.ja
> > va:108)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174
> > )
> > >>>
> > >>> at
> > >>>
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.proces
> > sConnection(Http11BaseProtocol.java:665)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.j
> > ava:528)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollower
> > WorkerThread.java:81)
> > >>>
> > >>> at
> > >>>
> >
> org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.j
> > ava:689)
> > >>>
> > >>> at java.lang.Thread.run(Thread.java:619)
> > >>>
> > >>>
> > >>
> > >