You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by juminoz <ju...@hotmail.com> on 2011/05/17 18:24:17 UTC

Checking Session Timeout

Am I correct that the only way to check for session timeout is to actually
explicitly do something with the session object (i.e. call a method in
Session class)? I thought that isAuthenticated() method returns false when
user is either not authenticated or that the session has already timed out,
but that doesn't seem to be the case. If I don't place a logic to explicitly
check, my client still can do everything as if the session hasn't timed out.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6373753.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Is There a Way to Manually Unbind Thread After Login

Posted by Jared Bunting <ja...@digitalreasoning.com>.
That seems like the appropriate way to do it, and basically mimics what
the Servlet Filters do.

On 05/18/2011 05:09 PM, juminoz wrote:
> Just FYI.
>
> I found the unbindSubject() method under ThreadContext class. With the
> approach I laid out in the last message, things are now working as expected.
>
> I basically unbind the thread when it's completed a task so that when it
> services the next request, the thread is cleaned and if there is no session
> ID in subsequent requests, the service simple throw
> UnauthenticatedException.
>
> Thanks,
> Jack
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6379729.html
> Sent from the Shiro User mailing list archive at Nabble.com.


Re: Is There a Way to Manually Unbind Thread After Login

Posted by juminoz <ju...@hotmail.com>.
I have a couple simple goal. Enabling security while minimizing overhead of
interaction with a user management system. At this point, it's pretty safe
to assume that no unauthenticated requests are allowed as well. There might
be certain exception cases, but that I can be dealt with later. Performance
really matters for this framework.

To achieve the goal, I'm planning to do:

1) Cache session information into Coherence after first request (which also
login). This is when I want to unbind the thread completely after execution.
2) Use session ID instead of username/password for all subsequent
interaction. Build subject manually using session ID.
3) Invalidate the cache only if there is any change to password.
4) Cache implied permissions (OR of user/group/sub group permission of a
subject/dual subjects).
5) Invalidate permissions when there is any change.
6) Session most likely never expire in most cases. Session is destroyed
through logout command.
7) All requests are proxied through for authentication while each method
requiring authorization explicitly invoke isPermitted().

Interacting with user management system is expensive and is always a
bottleneck, especially if they don't have caching mechanism of its own. It's
not unusual to see 70% performance drop when enabling
authentication/authorization (network overhead, various calculations, etc).
The cache is planned to be as close to the using applications as possible
(possibly on the same machine or at least location).

Because of this, logging in every time simply doesn't work (i.e. calling
user management system). I was told that authentication info will be cached
in Shiro 1.2.0. With the new feature, if grabbing the session is as
expensive as logging in every time against cached authentication info, then
I might as well perform a login every time.

I hope it is clearer about what I'm trying to do. I'm definitely open to
ideas if there are shortfalls to this approach.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6383065.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Is There a Way to Manually Unbind Thread After Login

Posted by Les Hazlewood <le...@hazlewood.com>.
Hi Jack,

On Thu, May 19, 2011 at 9:15 AM, juminoz <ju...@hotmail.com> wrote:
> Hi Les,
>
> Thanks for the pointer.
>
> Does manually creating a subject also create a put a session in the cache?

Nope - a session is only created (currently) when calling
subject.getSession() or subject.login.

> The reasons I wanted the thread unbound right after login are as follow:
>
> 1) Request to login does nothing more than just a login. If the
> session/subject can be cache by manually creating the subject, I think that
> may work out better as you suggested.

If I understand your scenario correctly, it doesn't matter what type
of request is being executed.  If your framework code transparently
creates, binds and then unbinds a Subject for every request (e.g.
exactly as the ShiroFilter does for a web app), it will work in all
cases, login or not.

To illustrate, this will login and cleanup the thread immediately after login:

//build the subject however you want from the message or request,
//perhaps using a sessionId.
Subject subject = new Subject.Builder().whatever....buildSubject();

final AuthenticationToken token = //get/create token based on the request

subject.execute(new Runnable() {
    public void run() {
        SecurityUtils.getSubject().login(token);
    }
});
//thread is 'clean' here

But the problem with this code, from a framework perspective at least,
is that it will *only* perform a login.  It will not work for any
other type of request or message.  Without understanding your scenario
further, one would assume that you want to be able to enable security
while processing any request or message - not just the login ones.  If
that is the case, the above code is not ideal since it can't handle
other types of requests.

HTH,

Les

Re: Is There a Way to Manually Unbind Thread After Login

Posted by juminoz <ju...@hotmail.com>.
Hi Les,

Thanks for the pointer.

Does manually creating a subject also create a put a session in the cache?
The reasons I wanted the thread unbound right after login are as follow:

1) Request to login does nothing more than just a login. If the
session/subject can be cache by manually creating the subject, I think that
may work out better as you suggested. Basically, the logic for the client
application would then be "if there is no session ID, send username/password
with the request". This will eliminate request to login completely. The
username/password may then contain 2 usernames and 2 passwords, 1 for app
user and 1 for end user (when end user is actually relevant). Subject will
then represent the combination. Otherwise, just username/password. All
permissions are AND'ed in the framework (app user permission, end user
permission, group/subgroup permissions).

2) Subject.login() binds subject to the current thread and even after
execution, it doesn't automatically unbind. If this is the only way to
create a session, I will probably still want to unbind the thread manually
after logging in. The goal is to use session ID for all subsequent requests
as long as the session is still alive.

I will trace through how Shiro works internally to find out more.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6382670.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Is There a Way to Manually Unbind Thread After Login

Posted by Les Hazlewood <lh...@apache.org>.
Also note that if you call execute as shown, any dispatching to other
threads via Shiro's SubjectAwareExecutor, SubjectAwareExecutorService,
and SubjectAwareScheduledExecutorService components will automatically
retain the Subject and perform automatic cleanup.

For example:

subject.execute(new Runnable() {
    public void run() {
        //subject is thread-bound here
        doSomethingConcurrently();
    }
}

//subject is NOT thread-bound here

public void doSomethingConcurrently() {
    //subject is thread-bound here

    Collection<Callable> tasks = //get tasks

    //the returned service instance must be one of Shiro's
    //SubjectAware* implementations, but note that with DI
    //this method isn't aware of Shiro APIs at all:
    ExecutorService execSvc = getExecutorService();

    //each task will be able to call SecurityUtils.getSubject()
    //successfully, with the current Subject being retained.
    //when each task is done, its thread will be cleared of
    //the Subject automatically:
    List<Future> results = invokeAll(tasks);
}

HTH,

Les

Re: Is There a Way to Manually Unbind Thread After Login

Posted by Les Hazlewood <lh...@apache.org>.
On Wed, May 18, 2011 at 6:42 PM, juminoz <ju...@hotmail.com> wrote:
> Yes, I think I potentially can do it that way, but I will need to look into
> how to do it with the constraints I have currently.
>
> What I'm doing is building a framework so that developer can use it to
> develop their applications. Doing it my way definitely seems risky since
> it's possible that developer forget to unbind the thread after each task.
>
> Anyway, it seems like I need to unbind the subject from the thread right
> away after login.

Why would you ever do this?  Most people want the authenticated
Subject instance available for the rest of the request so they can use
it to perform security checks at any point during the request.

In any event, in a non-web request/message scenario, nothing is bound
to the thread by default.  If you call SecurityUtils.getSubject()
however, it will automatically (lazily) create a Subject instance and
bind it to the thread if one does not yet exist.

If you don't want anything bound to the thread in a framework
development scenario, don't use SecurityUtils to set-up the initial
Subject instance.  Instead, it would work like the following:

Message message = //get message somehow

//nothing is bound to the thread at this point

//build a subject instance based on the incoming message
//the 'buildSubject' method would use Subject.Builder to build the
Subject instance
Subject subject = buildSubject(message);

//nothing is bound to the thread at this point

subject.execute(new Runnable() {
    public void run() {
        //the Subject is bound to the thread here!
    }
});

//nothing is bound to the thread at this point.

Notice how SecurityUtils was not used.  SecurityUtils is to make the
lives of application developers easy.  Framework developers will not
use it that often however, and instead rely on building the subject
and calling execute as shown above.

HTH,

Les

Re: Is There a Way to Manually Unbind Thread After Login

Posted by juminoz <ju...@hotmail.com>.
Yes, I think I potentially can do it that way, but I will need to look into
how to do it with the constraints I have currently.

What I'm doing is building a framework so that developer can use it to
develop their applications. Doing it my way definitely seems risky since
it's possible that developer forget to unbind the thread after each task.

Anyway, it seems like I need to unbind the subject from the thread right
away after login. What's a proper way of doing that? Do I do
subject.execute() on a Callable that doesn't do anything? Right now, logging
in without unbinding the thread is opening up a hugh security hole. Any call
that is serviced by that thread can "pretend" to be the authenticated user
without having to do anything. So I should just ignore this fact and do a
check on session ID every time? I guess that will work since nothing that
requires user to be authenticated will get executed without session ID.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6380344.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Is There a Way to Manually Unbind Thread After Login

Posted by Les Hazlewood <le...@hazlewood.com>.
The ThreadContext is really an internal support class for Shiro and
not really intended to be used by end-users.

The ideal scenario is I think this:

1.  Based on the incoming message/request/whatever, use the
Subject.Builder to build your subject instance.
2.  Call subject.execute and call whatever method is at the 'root' of
your chain., e.g.

subject.execute(new Runnable() {
    public void run() {
        myRootMethod();
    }
});

from myRootMethod() and anywhere below it in the call stack,
SecurityUtils.getSubject() will work correctly.  When subject.execute
returns, the thread's state will be as it was before calling execute -
it performs automatic cleanup.

This is exactly what the ShiroFilter and the
SecureRemoteInvocationExecutor do to ensure thread association and
automatic cleanup.

Is this not possible in your scenario Jack?

Cheers,

Les

Re: Is There a Way to Manually Unbind Thread After Login

Posted by juminoz <ju...@hotmail.com>.
Just FYI.

I found the unbindSubject() method under ThreadContext class. With the
approach I laid out in the last message, things are now working as expected.

I basically unbind the thread when it's completed a task so that when it
services the next request, the thread is cleaned and if there is no session
ID in subsequent requests, the service simple throw
UnauthenticatedException.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6379729.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Is There a Way to Manually Unbind Thread After Login

Posted by juminoz <ju...@hotmail.com>.
Les,

I think I figured out how I can get things to work with the JMS use case,
but I need to be able to unbind thread from the current subject at login. Is
there a way to do this? I saw that there is a way to create an bind/unbind
SubjectThreadState object with a subject, but how to I get access to it
after I login?

Here're the steps of what I think will work:

1) Send a JMS message to login. Unbind the current thread right away so the
session remains in the cache, but the thread is clean. A token with session
id is sent back to the client, which will be used for subsequent requests
related to the same user.
2) For every request, include the token in the JMS message. Service provider
then use this token to get the session and subject. Then bind the subject to
the current thread.

The issue I saw in my last try as mentioned in the last message in thread is
that the thread is associated with a subject permanently until I send a
command to logout. This means that any subsequent calls can do everything
without having to be authenticated or authorized since Shiro assumed that
it's the same user. Because of that, I want to be able to clear the thread
state, but leave the session in the cache for further usage.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6379566.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Checking Session Timeout

Posted by juminoz <ju...@hotmail.com>.
Hi Les,

Thanks for the response. To see if I understand it correctly, I setup a
simple experiment using a JMS service with 2 JMS clients. I simply ran the
test in Eclipse so everything is single-threaded.

Anyway, here's the steps:
1) Start JMS service
2) Start JMS clients (2 instances of the same client, using the same
username/password)
3) Send a message to login (server reacts to the message with property
"operation=login" by logging the user in)
4) Send a message to execute some logic that requires permission from 2nd
client -> successful
5) Send a message to execute some logic that requires permission from 1st
client -> successful

I'm not sure everything was executed successfully because the server is
single threaded, but I never once had to bind subject to the thread myself.
My login method basically executes this line using username/password from
the JMS message

SecurityUtils.getSubject().login(<username_password_token>);

and the logic execution invokes

SecurityUtils.getSubject().isPermitted(<permission_string>);

before execute the logic. I'm not sure if I understood your response
correctly. I thought for non-web application, I always have to bind the
subject to the thread to make it work. Or did you mean I have to do it when
I spawn off another thread? I took a look at the Spring example and looks
like I would have to bind the subject to the thread of the subsequent calls.
That's not what I'm seeing in my experiment. My guess is that I should be
doing the following:

1) Login for every request. I can't see how the service knows which client
is authenticated. It only knows which user is authenticated. It seems that I
also need to clear the thread since subsequent calls is automatically bound
to the same subject otherwise.
2) If I spawn off a thread, I need to bind a subject to that thread using
sessionId.

Sorry, I usually get it better with an example.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6376431.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Checking Session Timeout

Posted by Les Hazlewood <lh...@apache.org>.
On Tue, May 17, 2011 at 12:58 PM, juminoz <ju...@hotmail.com> wrote:
> I'm currently not explicitly storing Subject anywhere since I thought the
> framework automatically handles both subject and session. I basically
> assumed that subject stays around until session expires (may never expire).

The notion of a Subject (i.e. 'user') and its session function as you
expect them to.

I was talking about Shiro's implementation details, which are only
relevant if you _don't_ use SecurityUtils.getSubject() in your code
(for example, if you call SecurityUtils.getSubject() and then save the
returned instance as a class attribute in a long-lived object - this
would cause indeterminate behavior).  If you call
SecurityUtils.getSubject() (or use something that calls that on your
behalf) whenever you need to interact with a Subject instance, you're
ok.

I apologize if I confused anyone!

> Now I'm actually a little confused about how's it supposed to work. Brian
> mentioned in other thread that I should just keep sessions open and never
> actually log out so that authorization info stays in the cache.
>
> http://shiro-user.582556.n2.nabble.com/Authorization-Cache-Removed-when-Logged-Out-td6360724.html
>
> If subject is supposed to be short-lived, Brian's suggested approach is not
> recommended then?

Brian's suggestion is perfectly sound.  But it is sound because the
cache infrastructure doesn't cache Subject instances themselves - it
works because the underlying data that eventually makes up a Subject -
the AuthenticationInfo, AuthorizationInfo, and Session instances - are
what is cached.

> My use cases is as follow:
>
> Note: Client can be web or non-web. Web client may also invoke non-web
> client to invoke non-web service.
>
> 1)
> - Client login with at connection time
> - Client logout when disconnect
>
> 2)
> - Client login with when impersonate a user invoking client to call service
> (username: <app user>/<end user>)
> - Client logout after completion of impersonated call
>
> Subject in the second use case is short-lived, but long-lived otherwise. My
> goal is to cache both authentication and authorization info in the cache so
> that in high-volume transactions scenario, the bottleneck on ACL is
> minimized.

Yep, this won't be a problem.  The key to making this work however is
that for non-web clients, something needs to set up the Subject
instance before the thread executes and something needs to clean up
the thread after it is complete (or fails).

In a web environment, the root Shiro Filter does this setup/teardown
logic per web request automatically.  If not in a web environment, you
(or likely some framework) must do this instead.

You can see an example of this working in a non-web request scenario
by viewing Shiro's Spring Remoting support:

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

(see the subject.execute call).

This is also explained in detail in Shiro's Subject documentation:
http://shiro.apache.org/subject.html
Specifically, the Subject.Builder and 'Thread Association' sections.

Does this help?

Cheers,

Les

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com

Re: Checking Session Timeout

Posted by juminoz <ju...@hotmail.com>.
I'm currently not explicitly storing Subject anywhere since I thought the
framework automatically handles both subject and session. I basically
assumed that subject stays around until session expires (may never expire).

Now I'm actually a little confused about how's it supposed to work. Brian
mentioned in other thread that I should just keep sessions open and never
actually log out so that authorization info stays in the cache.

http://shiro-user.582556.n2.nabble.com/Authorization-Cache-Removed-when-Logged-Out-td6360724.html

If subject is supposed to be short-lived, Brian's suggested approach is not
recommended then?

My use cases is as follow:

Note: Client can be web or non-web. Web client may also invoke non-web
client to invoke non-web service.

1) 
- Client login with at connection time
- Client logout when disconnect

2) 
- Client login with when impersonate a user invoking client to call service
(username: <app user>/<end user>)
- Client logout after completion of impersonated call

Subject in the second use case is short-lived, but long-lived otherwise. My
goal is to cache both authentication and authorization info in the cache so
that in high-volume transactions scenario, the bottleneck on ACL is
minimized.

Thanks,
Jack

--
View this message in context: http://shiro-user.582556.n2.nabble.com/Checking-Session-Timeout-tp6373753p6374925.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Checking Session Timeout

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

The current Subject implementation (DelegatingSubject)
isAuthenticated() implementation assumes that your Subject instances
are very short lived - i.e. they are created and destroyed per request
(it initializes the 'authenticated' boolean in the constructor - not
by checking the session).

Do you use long-lived Subject instances?  I.e. do you store them in
static memory or in an HttpSession?

Regards,

Les

On Tue, May 17, 2011 at 9:24 AM, juminoz <ju...@hotmail.com> wrote:
> Am I correct that the only way to check for session timeout is to actually
> explicitly do something with the session object (i.e. call a method in
> Session class)? I thought that isAuthenticated() method returns false when
> user is either not authenticated or that the session has already timed out,
> but that doesn't seem to be the case. If I don't place a logic to explicitly
> check, my client still can do everything as if the session hasn't timed out.
>
> Thanks,
> Jack