Hi Tauren,

This is probably only solved if you are using Shiro's 'native'
sessions and not the Servlet container's default sessions.  If you
have a SessionDAO implementation that you can inject into the
SecurityManager, you can store sessions to your own data store if you
wish.

If that data store provides a queryable interface, like an RDBMS or
many enterprise Caches (GigaSpaces, Coherence, etc), you could obtain
this information very easily by querying against attributes on the
session directly.

For example, to see the number of open sessions (some could be timed
out though and not yet validated), you could execute a query something
like this:

"select count(*) from Session s where s.stopTimestamp is null"

That is, return the number of all Sessions that haven't been
invalidated yet.  But note that this could give you the number of some
sessions that are technically invalid but Shiro hasn't had the
opportunity to run its ValidationScheduler to 'reap' the orphan
invalidated sessions.  So instead, you'd have to refine your query a
little bit:

You could constrain it a little further to guarantee the session
hasn't timed out and they are still 'active' based on their last
access timestamp.  This would eliminate any yet-to-be-invalidated
sessions from the query results.  For example:

"select count(*) from Session s where s.stopTimestamp is null and
s.lastAccessTime > ?", where '?' equals (current timestamp
milliseconds - sessionTimeoutMilliseconds).

To find all the currently logged in users, you can subclass Shiro's
SimpleSession class and have an additional 'user id' field on that
class.  Implement a Shiro AuthenticationListener and register it with
the SecurityManager to listen for successful authentication attempts,
and then associate the user id onto your SimpleSession subclass
instance.  Then you can query against this field (along with the
timestamps above) to get all currently active logged-in users, i.e.

"select s.userId from Session s where s.stopTimestamp is null and
s.lastAccessTime > ?".

I've done these things for a few of my applications that need this
kind of session-based detail, and it works well.  Use an enterprise
cache if you can to improve performance - if you have one that
supports SQL-like queries, then that's the best possible scenario -
since all active sessions would live in the enterprise cache, you
could query it directly and not incur the more-expensive trip to a
relational database.

Finally, if you need to react to when sessions are started or stopped
or expired, you can implement the SessionListener interface and
register that with the SecurityManager as well.  Just realize that
session expiration events are only received when Shiro has the ability
to expire them based on a regular time interval.  Only start/stop
session events are received the instant they occur.

Best,

Les

On Mon, Jul 27, 2009 at 3:11 PM, Tauren Mills<[email protected]> wrote:
> A web application I am building needs to track users who are currently
> online.  For instance, I want to be able to do the following:
>
> 1. Show the total number of currently logged in users.
> 2. Show a user a list of their associates who are online (similar to
> how facebook chat shows a list of your friends who are currently
> online)
> 3. Allow an administrator to have a live list view of all currently
> logged in users
>
> Are there any features in Shiro that would help me with any of this?
> I'm thinking this would need to be handled by my application and that
> Shiro won't help. But I want to make sure this is the case before
> moving forward.
>
> As this is a web app, I would need to somehow keep track of session
> inactivity to determine if a user is "away" or if they've been
> automatically logged out due to session timeout.
>
> Thanks!
> Tauren
>

Reply via email to