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/18 23:22:28 UTC
Re: Is There a Way to Manually Unbind Thread After Login
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: 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.