Hi Jason, Typically debug levels for 3rd party frameworks are not viewed all that often - just during debugging only. Is there any reason why you have the DefaultSecurityManager's debug level turned on regularly?
A reasonable solution for this is to turn the log level for just the DefaultSecurityManager class to info. Is that not a valid solution? I'm trying to see why you'd want Shiro's logging level to be trace or debug - most people have it as WARN in production systems and INFO while developing. In any event, I just committed a fix to trunk where the message still prints at debug, but will display the invalidly referenced sessionId instead of the stack trace. But I added a trace log message to show the stack trace so it is not lost if ever needed. Regards, Les On Wed, Feb 3, 2010 at 9:50 PM, Jason Eacott <[email protected]> wrote: > Hi All, > I've been using Shiro with the code below for a while, and its fine, but > it always logs an annoying DEBUG with an exception stack trace the first > time a subject is seen and shiro caches a new sessionId: > "org.apache.shiro.mgt.DefaultSecurityManager - Context referenced sessionId > is invalid. Ignoring and creating an anonymous (session-less) Subject > instance. > org.apache.shiro.session.UnknownSessionException: There is no session with > id ... > at > org.apache.shiro.session.mgt.eis.CachingSessionDAO.readSession(CachingSessionDAO.java:281) > ... > > its logged on line 408 of the DefaultSecurityManager with > log.debug("Context referenced sessionId is invalid. Ignoring and > creating an anonymous " + > "(session-less) Subject instance.", e); > > it happens during my > subject = new > Subject.Builder(securityManager).sessionId(sessionId).buildSubject(); > > the problem is thrown, caught and handled within shiro, and my following: > subject.getSession(true); > sorts it all out. > > is it necessary to log this in Shiro? and if so, its debug so is it > necessary to include the stacktrace? > > > Thanks > Jason. > > > > Jason Eacott wrote: >> >> >> Les Hazlewood wrote: >>> >>> On Mon, Dec 21, 2009 at 3:36 AM, Jason Eacott <[email protected]> >>> wrote: >>>> >>>> ok, >>>> I did as you described, something like this in conjunction with a simple >>>> sessionDao as you described: >>>> >>>> //gets or creates a session with the given sessionId >>>> public Subject getSubjectBySessionId(String sessionId){ >>>> Subject subject =null; >>>> try { >>>> newSessionId.set(sessionId); >>>> subject = new >>>> Subject.Builder(securityManager).sessionId(sessionId).buildSubject(); >>>> subject.getSession(true); >>>> } >>>> } finally { >>>> newSessionId.remove(); >>>> } >>>> return subject; >>>> } >>>> >>>> and it works. thank you. >>> >>> Glad to hear it. >>> >>>> it did take me a while to figure out what was happening though, and to >>>> realise that the session isn't created until subject.getSession(true) is >>>> called (or something else touches the session) so when I fist did this I >>>> didnt have the getSession(true) step, so it failed. >>> >>> Yes, due to the fact that sessions naturally consume resources (i.e. >>> memory), Shiro will only create a session if necessary. By default, >>> once a user is logged in, a session is created for them as well since >>> Shiro will store Subject information (principals, etc) in the session. >>> This is also to retain the behavior that people are accustomed to >>> with HttpSessions. >>> >>>> I spent some time trying to figure out if I could either access my >>>> XmppMemorySessionDAO via the api, or inject a pre instantiated one >>>> somewhere >>>> but it seems not possible? >>>> >>>> it also took me a little while to find & figure out how to instantiate >>>> everything with the new config factory. >>> >>> Are you configuring Shiro in .ini or a spring.xml file? There is >>> usually no need to reference or use a SecurityManager Factory >>> implementation directly... >> >> I'm 'configuring' shiro with the .ini - I dont know how its done in >> spring. >> >> the reason I wanted the access was because my little hack class (here): >> ---------------- >> public class XmppMemorySessionDAO extends MemorySessionDAO { >> /** >> * @see >> org.apache.shiro.session.mgt.eis.MemorySessionDAO#generateNewSessionId() >> */ >> �...@override >> protected Serializable generateNewSessionId() { >> if(SecureMethodInterceptor.newSessionId.get()!=null){ >> return SecureMethodInterceptor.newSessionId.get(); >> } >> else >> { >> return super.generateNewSessionId(); >> } >> } >> } >> ---------------------- >> >> when I created this I wanted to keep the threadlocal in here too, but I >> couldnt find a way to get a reference to the instantiation in order to set >> it. I then tried to find a way to instantiate it myself (so I'd have a >> reference) and inject it into shiro, but couldnt see how. so my last option >> was a direct ref to a static threadlocal in my interceptor >> (SecureMethodInterceptor.newSessionId). >> >> >> I'm configuring 'the use' of Shiro using spring - eg: >> >> <bean id="securityManagerFactoryBean" >> class="org.apache.shiro.config.IniSecurityManagerFactory"/> >> >> <bean id="securityManager" factory-bean="securityManagerFactoryBean" >> factory-method="getInstance"/> >> >> <bean id="propertiesRealm" >> class="org.apache.shiro.realm.text.PropertiesRealm"/> >> >> <bean id="configurerAuth" >> class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> >> <property name="targetClass" value="org.apache.shiro.SecurityUtils"/> >> <property >> name="targetMethod"><value>setSecurityManager</value></property> >> <property name="arguments"> >> <list> >> <ref bean="securityManager" /> >> </list> >> </property> >> </bean> >> >> <bean id="secureMethodInterceptorAdvice" >> class="com.mvc.aop.SecureMethodInterceptor"> >> <property name="securityManager" ref="securityManager" /> >> </bean> >> >> >>> >>>> I'd like to ask that the other examples be updated (not just the >>>> quickstart) >>>> to reflect the changes. >>> >>> Please create a Jira issue for this for the 1.0 release so we don't >>> forget about it. I think this is a good idea, but if it is not in >>> Jira, it won't get done (easy to slip through the cracks when so many >>> other things are on the mind). >> >> ok >> >>>> I'd also like to suggest a standalone spring example so that its easy to >>>> see >>>> & duplicate exactly what needs to be created for folk not using either >>>> of >>>> the spring entrypoints offered. >>> >>> Could you elaborate on this a little more? Or maybe clarify in the >>> Jira issue? What entry points do you mean, and if they are not >>> sufficient, what more would you like supported? I use Spring all the >>> time with Shiro, so if there is something better that we can do, I'd >>> be very happy to work on this since it would naturally benefit me too >>> ;) >> >> well the examples that seem relevant are SecureRemoteInvocationExecutor, >> AopAllianceAnnotationsAuthorizingMethodInterceptor, and the 2 spring >> examples, both of which use the web.xml and the filter impl. >> I was looking for a quickstart standalone spring config. >> >> >>>> one last thing I noted, there seem to be a lot of method calls made for >>>> any >>>> interaction with the api. for example, whenever an attribute is got/put >>>> from >>>> an already aquired session, the internal session reference seems to be >>>> rediscovered quite a lot. >>> >>> Yes - with the exception of the simple memory-only Realms (IniRealm, >>> PropertiesRealm, SimpleAccountRealm), Shiro's architecture is 100% >>> stateless. It relies on caching (either done via a CacheManager/Cache >>> instances) or the underlying SessionDAO implementation or Transaction >>> mechansims to perform memory and/or thread-local caching themselves to >>> ensure that frequent Session lookups will be efficient. >> >> I'm using the propertiesRealm (without ehcache configured), and it still >> bounces around a lot. >> >>> If you think this should be different (say, Shiro does thread-local >>> Session caching as well), please feel free to open a Jira improvement >>> issue and we can talk about strategies for this on the dev list. >> >> not sure, I'm just surprised at how much work the already retrieved >> session has to do to fetch a simple attribute value, as I expected it to be >> a direct ref to a map. >> >> one quick, unrelated, very small change that could be made with the >> DefaultCacheManager would be to swap the HashMap for a ConcurrentHashMap & >> lose (or at least shrink if u dont like the approach below) the sync block. >> >> eg: >> public Cache getCache(String name) throws CacheException { >> if (name == null) { >> throw new CacheException("Cache name cannot be null."); >> } >> >> Cache cache, newVal; >> do { >> cache= caches.get(name); >> newVal = (cache== null) ? new SoftHashMapCache(name):cache; >> } while (!caches.replace(name, cache, newVal)); >> >> return newVal; >> } >> >> >> Cheers >> >> >> >> >> >> >> >
