You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by John Moore <gr...@jmsd.co.uk> on 2013/05/06 22:22:04 UTC

Storing objects in shared session

I'm using Shiro with Grails, for Single Sign On and shared sessions, 
with Redis as a backing store. It's working fine for most stuff, but 
there's a little problem I've run into which I would hope to be able to 
work around, although I'm wondering if it might be unavoidable.

I have two applications, let's call them myapp1 and myapp2, sharing 
sessions, so that when I am authenticated in myapp1 I can store a string 
value, say, in the session, switch to myapp2 without having to sign in, 
and then retrieve the value from the session. With strings, etc., and 
any classes which are defined in both applications, this works fine. 
Let's say I have a serializable class called Policy in myapp1, though, 
which is not present in myapp2. I can store a Policy object in the 
session in myapp1, but as soon as i switch to myapp2 an exception is 
thrown because of the missing class, without my having made any attempt 
to retrieve this Policy object from the session. That is, merely loading 
the shared session in myapp2 is enough to cause the problem.

I'm wondering whether this is something I may be able to do something 
about - if so what? Or is it intrinsic? In the meantime I'm actually 
marshalling the domain objects in question to JSON and storing them as 
JSON strings in the session (and unmarshalling them back to Java 
classes, of course). This is workable but an extra step I'd prefer to 
avoid if I could.

Re: Storing objects in shared session

Posted by Les Hazlewood <lh...@apache.org>.
Hi John,

The easiest way around this is to ensure that the same classes exist in
both applications.  Since that doesn't seem too practical, I think your
current approach is a good one.

However, another technique that I think could work (although laborious and
not something I've tried myself), would be to write a custom SessionDAO
implementation that stores attributes separately from the core Session
properties (last access timestamp, etc).  Then you could, when
deserializing the data, pull the core session data + shared session
attributes + app specific session attributes and make them available to
Shiro.  Almost as if the Session that Shiro sees would be a subset 'view'
of the overall data.

In Redis or other cache mechanisms, I suspect you could use 3 entries to
store data:

Entry 1 (sessions): key: sessionId, value: Shiro's native session
properties (lastAccessTimestamp, etc).
Entry 2 (shared session attributes): key: sessionId +
"_shared_session_attributes", value: map of shared session attributes
Entry 3 (app-specific session attributes): key: sessionId + "_" +
applicationId + "_session_attributes", value: map of app-specific session
attributes

Then on deserialization, you can pull the three entries and combine them
into a single Session object instance handed back to Shiro.

You'd also might need a custom Session implementation (and SessionFactory
to instantiate it) that knows how to, when setting session attributes,
route which of the two maps (shared vs app-specific) the attribute should
be stored.

Anyway, these are just ideas, and I haven't tried them myself, but it might
lead to other ideas.

HTH,

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282

On Mon, May 6, 2013 at 1:22 PM, John Moore <gr...@jmsd.co.uk> wrote:

> I'm using Shiro with Grails, for Single Sign On and shared sessions,
> with Redis as a backing store. It's working fine for most stuff, but
> there's a little problem I've run into which I would hope to be able to
> work around, although I'm wondering if it might be unavoidable.
>
> I have two applications, let's call them myapp1 and myapp2, sharing
> sessions, so that when I am authenticated in myapp1 I can store a string
> value, say, in the session, switch to myapp2 without having to sign in,
> and then retrieve the value from the session. With strings, etc., and
> any classes which are defined in both applications, this works fine.
> Let's say I have a serializable class called Policy in myapp1, though,
> which is not present in myapp2. I can store a Policy object in the
> session in myapp1, but as soon as i switch to myapp2 an exception is
> thrown because of the missing class, without my having made any attempt
> to retrieve this Policy object from the session. That is, merely loading
> the shared session in myapp2 is enough to cause the problem.
>
> I'm wondering whether this is something I may be able to do something
> about - if so what? Or is it intrinsic? In the meantime I'm actually
> marshalling the domain objects in question to JSON and storing them as
> JSON strings in the session (and unmarshalling them back to Java
> classes, of course). This is workable but an extra step I'd prefer to
> avoid if I could.
>