Hi Jim, Please see inline:
I'm looking at using shiro in a (swing-based) client/server application,
using a "remoting" approach (like rmi, spring remoting, but this is a custom
implementation as I won't be using shiro's spring support) -- so the client
gets a remote proxy of some service interfaces that the server exports.
What I'm currently thinking is that authentication will be an explicit
operation that the client can perform, which will result in it acquiring a
session token that can be sent with each subsequent invocation request. The
server will use the session token provided by the client to add the
appropriate subject to the invocation context before the invocation is made.
It looks like I can use shiro's session id as the session token.
Yep, this is fairly common. We have a Java Web Start sample
application that you can use for ideas. It uses Spring remoting, but
the concepts are the same regardless of the remoting mechanism - you
just need to ensure that the session ID accompanies the remoting
payload somehow.
1. Can I create a session without logging in? This might be useful if we
implement some unprivileged client behavior which doesn't require login.
Yep, absolutely. A subject.getSession() call will return a new
session if one does not yet exist, regardless of
authentication/rememberMe state.
2. If the user logs in and then subsequently logs out (or is timed out), is
the session gone? Is the session id no longer valid? This would mean that
I would have to send a new session id to the client.
In the case of a log out or expiration timeout, any further
interactions under the old session ID would cause an
InvalidSessionException. It is the responsibility of the client (or
the server acting on behalf of the client) to catch these exceptions
and act accordingly (e.g. transparently create a new session, or show
the user some view to force a new login, etc).
For example, Shiro's web support does this automatically (since the
web layer is considered a client tier). If the client browser sends
an old session ID cookie, Shiro's web module will catch the exception
and transparently remove the old session id cookie. If the request
then needs a new session, the new session's id is automatically added
to the response as a new cookie.
As to whether or not if the session is 'gone': when a session is
stopped explicitly, or stopped automatically via logout, or expired
due to inactivity, in all cases that particular session is no longer
usable. However, the raw session data may still exist in the session
backing data store (abstracted in Shiro via a SessionDAO). The Shiro
SessionManager implementation's default behavior is to permanently
delete all sessions upon discovering they are stopped or expired.
However, this behavior can be turned off where it is expected that
some process external to Shiro will clean up the session store (e.g. a
Quartz job or cron job) to prevent long-term orphans. This feature
exists because some people want to run queries on the data store to
gather statistics about user's session usage (how long an average
session lasts, how many sessions per user, etc). (My personal feeling
is that this doesn't scale well and that queries should be run on
logged data sets, such as via Hadoop).
This may be a little more than what you were asking for, but just know
that in all cases, once a session has expired or is stopped, it can no
longer be accessed by the application - at least not through Shiro.
Finally, for rich client applications, the session.touch() method
might be of interest. It should be used appropriately to ensure that
sessions aren't left open forever, but it could be useful in some
situations. That method's JavaDoc should help clarify things.
3. I understand that I can use the following to look up a subject for a
given session:
subject = new
Subject.Builder(securityManager).sessionId(sessionId).buildSubject();
But what happens if the sessionId is not valid? Will I get a new
(unauthenticated) subject without a session? Will it implicitly create a
session? Will subject construction fail? In my case, if the session is no
longer valid I would need to construct a new session and then relay the new
session id to the caller.
The buildSubject() call in this case would fail with an
InvalidSessionException - the assumption is that because you're
providing a specific ID, you must know more than Shiro does that you
expect a session to be there.
However, it is quite easy to catch that exception and automatically
build a new Subject if that occurs. It is just hard for Shiro to do
this automatically because it is very specific to the client being
built, which is impossible for us to know about a priori. But if
anyone out there has suggestions to make this better, we're all ears!
Anyway, I hope that helps!
Best,
Les