You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Adam Gordon <ad...@readytalk.com> on 2007/11/13 22:16:59 UTC
JAAS and Struts Re-authentication Question
Hi-
We're using JAAS for webapp authentication and we've discovered an
issue: If user A is logged in and tries to log in as user B, they stay
logged in as user A. We know how to detect if a user's already
authenticated (we have some static objects stored on the session) but
we're not sure where to put the code that would detect whether user A
had an authenticated session and invalidate it before allowing them to
log in as user B.
I've tooled around with the LoginAction but am getting various Tomcat
errors (invalid reference to login page, attempt to post to
j_security_check and the servlet isn't available, etc...).
Any ideas?
--adam
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
See my comments in my response to Laurie. We're basically using dual
login pages, one on our main website (Apache) and the other in our
webapp. I'm currently toying with the idea of a Filter to detect the
subsequent logins against an already authenticated session.
--adam
Dale Newfield wrote:
> Laurie Harper wrote:
>> If you have a separate 'login' page (as opposed to having a login
>> form on each page) you might be able to get away with invalidating
>> the session when that page is shown, with the caveat that logged in
>> users would implicitly be logged out if they visit that page.
>
> And in the case where there's not a separate login page you could add
> an interceptor that's only in the stack of your login form, which
> invalidates the session. That way it's impossible for someone to get
> to the point where they'll be logging in while already logged in.
>
> -Dale
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Dale Newfield <Da...@Newfield.org>.
Laurie Harper wrote:
> If you have a separate 'login' page (as opposed to having a login form
> on each page) you might be able to get away with invalidating the
> session when that page is shown, with the caveat that logged in users
> would implicitly be logged out if they visit that page.
And in the case where there's not a separate login page you could add an
interceptor that's only in the stack of your login form, which
invalidates the session. That way it's impossible for someone to get to
the point where they'll be logging in while already logged in.
-Dale
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
So I think I have it working and I didn't have to redirect the user,
which is good because that wasn't working anyway. I don't know if it
was JAAS or Struts, or what, but the login parameters were being
stripped from the request so they never got to the login page.
How I got it to work was this:
I added a filter that looked for the login parameters on the request and
if the login was different from the login of the currently authenticated
user I retrieved the user's instance of their LoginModule (which I set
on the user principal in the login() method in the LoginModule
instance), called the logout method, which cleared the user's
information from the session (though it's not exactly clear how), and
then invalidate the session. For whatever reason, invalidating the
session wasn't sufficient to actually invalidate the session. The
user's information was still being persisted in the LoginModule instance
so my guess is that when the user tried to log in as another user, it
was still using the old user information bean.
The result of this is that if user A is logged in and authenticated and
this user attempts to log in as user B, we log out user A but since B's
login parameters are lost, user B is dumped to the login page where they
have to log in again. We can live with this for now since the only
reason we're implementing this fix is to prevent our CSR's and sales
team from accidentally forgetting to log out as one user and then try to
log in as another and do something to the first user's account when they
are thinking it's the second user's account.
I think ultimately, the solution is going to be to not use JAAS and
implement our own authentication solution since it's pretty clear that
either we're not using JAAS correctly, or it's just not capable of doing
what we need it to do.
Thanks for all the feedback.
--adam
Dale Newfield wrote:
> Adam Gordon wrote:
>> I think the solution is going to be to redirect the user to the
>> default main page manually w/ the login parameters and JAAS should
>> take over from there...hopefully.
>
> Except a redirect must be to a GET, not a POST, and it would be
> unfortunate to include the login credentials in a GET as they would
> then appear in history/logfiles...
> ...there's no way to do in code in your filter right where the problem
> case is detected the same stuff you do in a script on your login form
> page?
>
> -Dale
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
Yea, but in this case, it may be something we need to live with.
The login page scriptlet code looks for the login credentials in the
request and sets the appropriate form fields as well as a flag we use to
indicate whether the form should be submitted immediately upon loading
and in either case, it's a POST to j_security_check. I'm not sure I'll
be able to even configure a filter for what we need to do. Am testing
it now. We may need to forgo JAAS entirely and use an action servlet
instead.
--adam
Dale Newfield wrote:
>
> Except a redirect must be to a GET, not a POST, and it would be
> unfortunate to include the login credentials in a GET as they would
> then appear in history/logfiles...
> ...there's no way to do in code in your filter right where the problem
> case is detected the same stuff you do in a script on your login form
> page?
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Dale Newfield <Da...@Newfield.org>.
Adam Gordon wrote:
> I think the solution is
> going to be to redirect the user to the default main page manually w/
> the login parameters and JAAS should take over from there...hopefully.
Except a redirect must be to a GET, not a POST, and it would be
unfortunate to include the login credentials in a GET as they would then
appear in history/logfiles...
...there's no way to do in code in your filter right where the problem
case is detected the same stuff you do in a script on your login form page?
-Dale
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
> Let me get this straight: All pages in your webapp are protected (not
> available to non-logged in users), so when someone who is logged in on
> the company's main site tries to get to a page in your webapp, JAAS
> catches it and sends them to your webapp's login page, which might be
> able to glean enough details to log them in automagically and then
> redirect them to the originally requested page in your webapp. So
> you're relying on JAAS's restriction "non-logged in users can't get to
> these pages" to insert your webapp's login logic, but if the user *is*
> already logged in, there's noplace to catch this, so your webapp's
> login logic gets sidestepped.
Correct. We do have some pages which are accessible by non-logged in
users, but I don't believe that's relevant here. We have two security
constraints: the first locks everything down and says the webapp is
only accessible by users w/ the the role X (we only have one role and
either you're in that role or your not) and the second opens up specific
URIs to everyone (help docs, etc...).
> If a user is logged in as A and continues (using the site-wide login
> form) to log in as B, once in your webapp does request.getRemoteUser()
> return A or B? If it returns A then you have enough information to
> detect this case.
We have a request listener set up in web.xml that is hit for every
request. We use it to setup the user's navigation menus and stash some
static account information on their session for easier accessibility.
When user A logs in, for debugging, I'm printing out the full URL and it
has user A's login parameters and the value of getRemoteUser() returns
user A's username. With A's session still authenticated, I navigate
back to our main website and log in as user B and the full URL contains
user B's login parameters, but getRemoteUser() returns user A's
username. Detecting the case wasn't the issue. We could also do this
by looking for the account information on the session - if it's present
the session is authenticated, if not, it's not.
> Since you know how to detect the login parameters from the request,
> you could put in an interceptor that checks if the login parameter is
> present, and if it differs from request.getRemoteUser() then you have
> just detected the problematic case. Invalidate the session and then
> JAAS will catch that the user is no longer logged in, which will
> trigger the display of your webapp's login page, which will result in
> correct behavior.
This is the crux of the problem. In this request listener, I've placed
code that looks for the case above, i.e., user B's login parameters but
user A's authenticated session and in the case where B logs in over the
top of A, I've invalidated the session. I believe what's happening is
that JAAS correctly detects that the session is no longer authenticated
and redirects the user to the login page. However, this creates 2
problems: 1) I already have the user's credentials and don't need the
login form (which actually makes me think there's another issue as the
login parameters aren't getting passed to that login form) and 2) when I
try to log in via the form w/ B's credentials, I still get A's account.
Looking at the logs, I can see the login() method from the LoginModule
being called for B. I believe the wrong account problem is occurring
because the logout() method is never being called on the LoginModule for
user A. And as we've already discussed in this thread, there's not
really any way to call the logout() method. I think the solution is
going to be to redirect the user to the default main page manually w/
the login parameters and JAAS should take over from there...hopefully.
Only, you can't redirect a request from a RequestListener so I'm going
to see if I can set up a Filter since it has the required Response
object to do the redirect.
Thanks for all the info. If you have any other epiphanies please let me
know and I'll let you know how this turns out.
--adam
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Dale Newfield <Da...@Newfield.org>.
Adam Gordon wrote:
> For background, we actually have two login pages: on is the login page
> that is running inside our webapp that is running JAAS and POSTs to
> j_security_check at form submission time. The other page is our
> company's main website (Apache) and users can log in here too. What we
> do is perform a GET (either Struts or JAAS does not like doing POSTS w/
> parameters - it strips them off) to the default protected resource
> inside our webapp. What I believe to happen is that JAAS detects that
> the requested URI is protected so it redirects the user to the login
> page. I have a large scriptlet block at the top of the JSP page which
> looks for the login parameters (from the main website page) and uses
> them to try and authenticate. If it fails, JAAS dumps the user back at
> the webapp login page with the appropriate error message. If it
> succeeds, the user is placed at the default (protected) webapp page (or
> whatever page they originally requested).
Let me get this straight: All pages in your webapp are protected (not
available to non-logged in users), so when someone who is logged in on
the company's main site tries to get to a page in your webapp, JAAS
catches it and sends them to your webapp's login page, which might be
able to glean enough details to log them in automagically and then
redirect them to the originally requested page in your webapp. So
you're relying on JAAS's restriction "non-logged in users can't get to
these pages" to insert your webapp's login logic, but if the user *is*
already logged in, there's noplace to catch this, so your webapp's login
logic gets sidestepped.
If a user is logged in as A and continues (using the site-wide login
form) to log in as B, once in your webapp does request.getRemoteUser()
return A or B? If it returns A then you have enough information to
detect this case.
Since you know how to detect the login parameters from the request, you
could put in an interceptor that checks if the login parameter is
present, and if it differs from request.getRemoteUser() then you have
just detected the problematic case. Invalidate the session and then
JAAS will catch that the user is no longer logged in, which will trigger
the display of your webapp's login page, which will result in correct
behavior.
-Dale
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
I believe you are absolutely correct Laurie, because I've not yet seen a
way to get a handle to the LoginContext to call logout(). All we can do
is invalidate the session - which we do when the user logs out. This
removes the user principal from the request and indicates to JAAS that
the user is no longer authenticated meaning if they try to access a
protected resource they are prompted to log in again. Additionally,
while the core Request object has a setUserPrincipal(...) method, it is
not exposed by the HttpServletRequest Interface (and nor by the Wrapper
or Facade classes) so I can't even do it manually.
For background, we actually have two login pages: on is the login page
that is running inside our webapp that is running JAAS and POSTs to
j_security_check at form submission time. The other page is our
company's main website (Apache) and users can log in here too. What we
do is perform a GET (either Struts or JAAS does not like doing POSTS w/
parameters - it strips them off) to the default protected resource
inside our webapp. What I believe to happen is that JAAS detects that
the requested URI is protected so it redirects the user to the login
page. I have a large scriptlet block at the top of the JSP page which
looks for the login parameters (from the main website page) and uses
them to try and authenticate. If it fails, JAAS dumps the user back at
the webapp login page with the appropriate error message. If it
succeeds, the user is placed at the default (protected) webapp page (or
whatever page they originally requested).
All this works great and as designed. We have a LoginModule
implementation that is called implicitly by JAAS to authenticate the
user (the implementation ultimately uses database calls). The problem
occurs when someone goes back to our main website and tries to log in
again as user B when they are already authenticated as user A (i.e.,
they've not logged out). I believe JAAS takes a look at the request and
says "Ah! I see you're already authenticated and dumps the user back at
the default webapp page but with user A's credentials, not user B. In
this second case, the login page is never hit the second time which mean
I can't check to see if the session is already authenticated and force a
logout before logging in as the different user.
In my perusing of JAAS on the web I found the following comment:
"Although it is possible to use JAAS within Tomcat as an authentication
mechanism (JAASRealm), the flexibility of the JAAS framework is lost
once the user is authenticated. This is because the principals are used
to denote the concepts of "user" and "role", and are no longer available
in the security context in which the webapp is executed. The result of
the authentication is available only through request.getRemoteUser() and
request.isUserInRole()."
Hope that was clear.
--adam
Laurie Harper wrote:
> I don't think Container Managed Security has provisions for logging
> users out, other than by expiring the session (and not even then if
> you're relying on HTTP authentication rather than form-based).
>
> If you have a separate 'login' page (as opposed to having a login form
> on each page) you might be able to get away with invalidating the
> session when that page is shown, with the caveat that logged in users
> would implicitly be logged out if they visit that page.
>
> Perhaps it would help to more fully describe the use case (i.e. 'user
> is logged in and tries to log in...' and how it is failing (i.e. 'user
> stays logged in as old user'), along with specific details of how you
> have authentication configured.
>
> L.
>
> Adam Gordon wrote:
>> If you mean protecting the page w/ a security constraint, I think
>> that would be a problem in that JAAS would detect that it's a
>> protected resource and prompt the user to log in before hitting the
>> login page and upon a successful login would redirect the user to the
>> login page after they've already logged in. And even if I modified
>> the login page to redirect to the default home page in the webapp,
>> the problem is when they try logging in as someone else without
>> logging out - JAAS/Tomcat detects that they are already logged in
>> (have an authenticated session) and so would bypass any
>> authentication mechanism.
>>
>> --adam
>>
>> Dale Newfield wrote:
>>> Adam Gordon wrote:
>>>> We're using JAAS for webapp authentication and we've discovered an
>>>> issue: If user A is logged in and tries to log in as user B, they
>>>> stay logged in as user A.
>>>
>>> Couldn't you protect the login form page and action so that they're
>>> only accessible by a session without any valid login credentials?
>>> That way the only way to log in as B would be to first log out as A
>>> (or in some other way start a new session w/o A's credentials).
>>>
>>> -Dale
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>>> For additional commands, e-mail: user-help@struts.apache.org
>>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Laurie Harper <la...@holoweb.net>.
I don't think Container Managed Security has provisions for logging
users out, other than by expiring the session (and not even then if
you're relying on HTTP authentication rather than form-based).
If you have a separate 'login' page (as opposed to having a login form
on each page) you might be able to get away with invalidating the
session when that page is shown, with the caveat that logged in users
would implicitly be logged out if they visit that page.
Perhaps it would help to more fully describe the use case (i.e. 'user is
logged in and tries to log in...' and how it is failing (i.e. 'user
stays logged in as old user'), along with specific details of how you
have authentication configured.
L.
Adam Gordon wrote:
> If you mean protecting the page w/ a security constraint, I think that
> would be a problem in that JAAS would detect that it's a protected
> resource and prompt the user to log in before hitting the login page and
> upon a successful login would redirect the user to the login page after
> they've already logged in. And even if I modified the login page to
> redirect to the default home page in the webapp, the problem is when
> they try logging in as someone else without logging out - JAAS/Tomcat
> detects that they are already logged in (have an authenticated session)
> and so would bypass any authentication mechanism.
>
> --adam
>
> Dale Newfield wrote:
>> Adam Gordon wrote:
>>> We're using JAAS for webapp authentication and we've discovered an
>>> issue: If user A is logged in and tries to log in as user B, they
>>> stay logged in as user A.
>>
>> Couldn't you protect the login form page and action so that they're
>> only accessible by a session without any valid login credentials?
>> That way the only way to log in as B would be to first log out as A
>> (or in some other way start a new session w/o A's credentials).
>>
>> -Dale
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Adam Gordon <ad...@readytalk.com>.
If you mean protecting the page w/ a security constraint, I think that
would be a problem in that JAAS would detect that it's a protected
resource and prompt the user to log in before hitting the login page and
upon a successful login would redirect the user to the login page after
they've already logged in. And even if I modified the login page to
redirect to the default home page in the webapp, the problem is when
they try logging in as someone else without logging out - JAAS/Tomcat
detects that they are already logged in (have an authenticated session)
and so would bypass any authentication mechanism.
--adam
Dale Newfield wrote:
> Adam Gordon wrote:
>> We're using JAAS for webapp authentication and we've discovered an
>> issue: If user A is logged in and tries to log in as user B, they
>> stay logged in as user A.
>
> Couldn't you protect the login form page and action so that they're
> only accessible by a session without any valid login credentials?
> That way the only way to log in as B would be to first log out as A
> (or in some other way start a new session w/o A's credentials).
>
> -Dale
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org
Re: [struts] JAAS and Struts Re-authentication Question
Posted by Dale Newfield <Da...@Newfield.org>.
Adam Gordon wrote:
> We're using JAAS for webapp authentication and we've discovered an
> issue: If user A is logged in and tries to log in as user B, they stay
> logged in as user A.
Couldn't you protect the login form page and action so that they're only
accessible by a session without any valid login credentials? That way
the only way to log in as B would be to first log out as A (or in some
other way start a new session w/o A's credentials).
-Dale
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org