Bug 10526 - Authenticators do not always cache the Principal
Summary: Authenticators do not always cache the Principal
Alias: None
Product: Tomcat 4
Classification: Unclassified
Component: Catalina (show other bugs)
Version: Nightly Build
Hardware: Other other
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2002-07-06 13:11 UTC by John Holman
Modified: 2010-12-15 11:41 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description John Holman 2002-07-06 13:11:40 UTC
Once a user is authenticated a Principal object is supposed to be cached for 
the duration of the user's session. This is especially important when using 
JDBCRealm or JNDIRealm to reduce the load on external authentication services.

Most authenticators (BasicAuthenticator, SSLAuthenticator and 
DigestAuthenticator) call AuthenticatorBase.register()to cache the Principal. 
However register() does nothing if a session object does not already exist, so 
caching does not occur when the application does not create a session object 
itself. The problem can be seen by setting a security constraint on tomcat-docs 
and then browsing the Tomcat documentation - the external authentication 
service is hit on every request.

The problem does not occur with form based login, because FormAuthenticator 
caches the Principal itself and creates a new session if necessary to do it.

Probably the best fix would be to change AuthenticatorBase.register() to create 
a new session by calling getSession(request, true) instead of getSession
(request, false). However, perhaps there is a reason why this is not being 
done - though if so I cannot see what it is.

An alternative is to change the concrete authentication classes to make sure a 
session exists before calling register(), e.g.

--- BasicAuthenticator.java     23 Mar 2002 17:52:16 -0000      1.12
+++ BasicAuthenticator.java     6 Jul 2002 12:46:30 -0000
@@ -160,6 +160,7 @@
         String password = parsePassword(authorization);
         principal = context.getRealm().authenticate(username, password);
         if (principal != null) {
+           Session session = getSession(request, true);
             register(request, response, principal, Constants.BASIC_METHOD,
                      username, password);
             return (true);

Similar patches would be required for SSLAuthenticator and DigestAuthenticator 
of course.
Comment 1 Mark Thomas 2004-01-01 18:45:57 UTC
After a quick discussion on tomcat-dev, the conclusion is that this is by 
design. The patch proposed (to always create the session) will not be applied 
as it is not desirable in all circumstances to have a session created for 
every authenticated user.

However, if this was made a configurable option (defaulting to off) then this 
would be acceptable.

I am therefore marking this report as an enhancement request.

In the absence of the enhancement, there is always the option to create the 
session in your web application.
Comment 2 Mark Thomas 2010-12-15 11:41:47 UTC
Fixed in 7.0.x and will be in 7.0.6 onwards.