You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Bruce Mitchener <br...@gmail.com> on 2011/06/19 18:58:33 UTC

Non-web-based usage: sessions, auth, etc.

Hello,

I'm looking at using Shiro in a server application that runs in multiple
processes on multiple machines.  It doesn't have a typical web-frontend to
it, although there are some pieces that are exposed to the web.

I want to have sessions and such set up such that:


   - The client connects with a persistent connection to one of the servers.
   They're given a session ID and logged in.
   - The client can connect to other servers, provide that session ID and be
   automatically treated as a logged in user and hooked up to authorization
   correctly.


For some reason, I'm having a bit of a problem wrapping my head around all
of the pieces involved here, partially since there are so many different
classes, all layering on each other ...

So, to start, I've found that I can set up a credential matcher that always
succeeds which is fine since I can do that after our existing authorization
code runs. I've since forgotten where I found this code, but I can surely
find it again.

I've written a quick and dirty ZooKeeper-based cache for handling
distributed session storage for now to avoid adding EHCache or something to
our infrastructure in the next week or two. I can use that with the
EnterpriseCacheSessionDAO and plug that in somewhere so that all sessions
are persisted and retrieved from a ZooKeeper instance.

But, what's the right way to handle the sessionID stuff?

On the login server, call login on the subject and then get a session? How
do I ensure that's validated? Should I be storing something into the session
to tie it back to that user or is that already handled somewhere in an
appropriate way?

What are best practices for avoiding session hijacking and such? What
support is built into Shiro for helping out with that?

Hoping for a better understanding...

 - Bruce

Re: Non-web-based usage: sessions, auth, etc.

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

Did this help solve your problem? I'm curious about how the ZooKeeper
technique for sessions is working for you.

Cheers,

Les

Re: Non-web-based usage: sessions, auth, etc.

Posted by Les Hazlewood <lh...@apache.org>.
String sessionId = //get from somewhere - request or remote invocation, whatever
SecurityManager securityManager = //Shiro's SecurityManager from app's
Shiro setup
Subject subject = new
Subject.Builder(securityManager).sessionId(sessionId).buildSubject();

Then you'll want to bind/unbind the subject to/from the thread.

You can see an example of this get-by-session-id and then bind/unbind
logic in the Spring support module's SecureRemoteInvocationExecutor:

http://svn.apache.org/repos/asf/shiro/trunk/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java

The invocation represents a remote method invocation, and the session
id is acquired from the invocation's payload.

The most important part after the Subject is constructed is calling
the execute method to ensure the Subject is bound/unbound from the
thread automatically as the rest of the call stack executes.  Subject
building and bind/unbind options are covered in more detail here:
http://shiro.apache.org/subject.html in the "Custom Subject Instances"
section.

HTH,

-- 
Les Hazlewood
CTO, Katasoft | http://www.katasoft.com | 888.391.5282
twitter: http://twitter.com/lhazlewood
katasoft blog: http://www.katasoft.com/blogs/lhazlewood
personal blog: http://leshazlewood.com

Re: Non-web-based usage: sessions, auth, etc.

Posted by Bruce Mitchener <br...@gmail.com>.
Hi Les,

Thanks for all of the replies ... One remaining question (for now).

In a service where all I have is a session ID from the user, how do I go
from there back to having a valid and authenticated subject?

 - Bruce

Re: Non-web-based usage: sessions, auth, etc.

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

> I've written a quick and dirty ZooKeeper-based cache for handling
> distributed session storage for now to avoid adding EHCache or something to
> our infrastructure in the next week or two. I can use that with the
> EnterpriseCacheSessionDAO and plug that in somewhere so that all sessions
> are persisted and retrieved from a ZooKeeper instance.

Sounds good!

> But, what's the right way to handle the sessionID stuff?
> On the login server, call login on the subject and then get a session?

Yep, when you call login by default a session is created.  The user
identity (the Shiro Subject's PrincipalCollection) is stored in the
session by default (this will be configurable in 1.2).

The other way to create a session is to just call
subject.getSession();  In either case, just call session.getId() and
that's your 'handle' to get the session later.

> How do I ensure that's validated?

Shiro automatically validates the session when it is acquired.  For
example, if you use the Subject.Builder and provide a session ID, that
session ID is wrapped in a SessionKey instance.  The SessionKey is
submitted to the SessionManager's getSession(sessionKey) method.  That
method will (eventually, via subclass implementation) validate the
acquired session before returning it.

> Should I be storing something into the session
> to tie it back to that user or is that already handled somewhere in an
> appropriate way?

This shouldn't be necessary because the PrincipalCollection is stored
in the Session already (as a session attribute, and the attribute map
is serialized when persisting sessions).

> What are best practices for avoiding session hijacking and such? What
> support is built into Shiro for helping out with that?

It is assumed that non web apps transmit session ids in a secure
manner (e.g. SSH or SSL) to prevent MITM attacks.  Once in the client
application, it is up to the client to ensure it remains safe.  For
example, in a web app, the session ID cookie is set as an 'HttpOnly'
cookie to ensure JavaScript clients can't access it.

Other clients will need to perform similar logic themselves, but for
most apps, this is usually as simple as keeping it in
client-instance-specific runtime memory and never outputting it to
disk.

HTH,

-- 
Les Hazlewood
CTO, Katasoft | http://www.katasoft.com | 888.391.5282
twitter: http://twitter.com/lhazlewood
katasoft blog: http://www.katasoft.com/blogs/lhazlewood
personal blog: http://leshazlewood.com