You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Dale Newfield <Da...@Newfield.org> on 2007/11/14 00:40:18 UTC

Re: [struts] JAAS and Struts Re-authentication Question

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


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