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






Reply via email to