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 withlog.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 myXmppMemorySessionDAO via the api, or inject a pre instantiated one somewherebut 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).okI'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 ofthe 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 froman 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
