tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ken Johanson <>
Subject Re: Calling Realm.authenticate() doesn't register Principal in with the Session??
Date Fri, 10 Feb 2006 03:27:57 GMT
I'm trying to re-word these two concepts in a more elegant way:

1) I'm looking for a way to use form based authentication - but unlike 
with the current form login Realm, I need a way to intercept the persons 
email address(s) (typed into the username field), so that I can convert 
that into its corresponding username *before* passing it to the Realm 
(this cannot be done with the current form based login).

For this method, I would *prefer* not to write an override to any 
existing Realm (Form or WWW-Authenticate) - because users may already 
have their own. In other words, I would like to be able to call into 
whatever Realm the user already has configured (provided it's a 
user/pass one).

2) As an alternative, being able to simply register a given username 
(void doLogin(Principal p)) with a session via the server API would also 
be very useful - one could perform their own password or X509 validation 
inside of a servlet/jsp (using rules that are much more strict than what 
the current impls support, e.g trust levels/rules for issuers, and 
revocation checks, and critical subject flags for x509 certs). One could 
also implement the simplest possible (yet highly customizable) login 
logic against say, a database:

ResultSet rs = ps.exec("SELECT pass FROM auth WHERE user = ?"
if (Digest.sha1(request.getParameter("pass"))
  Tomcat5.doLogin(session, new Principal(request.getParameter("user"));

I hope that these two (very different) concepts will be tantalizing 
enough that some highly simplified auth APIs/concepts will make their 
way into the server. I have tried to build the first one - but the 
protected request/response fields in CoyoteRequestFacade cannot be 
accessed from a external class, and reflection would be needed to 
cast/call the method. An 'expert' will do much better than I.

class Tomcat5:

public static boolean tryLogin(HttpServletRequest request, 
HttpServletRequest response, String user, String pass)
   throws Exception
   Server server = ServerFactory.getServer();
   Service service = server.findService("Catalina");
   if (service==null)
     throw new NullPointerException("login: Cannot load Service 
   Engine engine = (Engine) service.getContainer();
   if (engine==null)
     throw new NullPointerException("login: Cannot load Container for 
Service 'Catalina'");

   Host host = null;
   String hostname = Strings.norm(request.getHeader("Host"));
   Object[] o = engine.findChildren();
   for (int i=0; i<o.length; i++)
     if (!(o[i] instanceof Host))
     Host h = (Host)o[i];
     String[] list = h.findAliases();
     for (int j=0; j<list.length; j++)
       if (hostname.equalsIgnoreCase(list[j]))
         host = h;
   if (host==null)
     throw new NullPointerException("login: Cannot load Host 
   String reqbase  = Strings.norm(req.getContextPath())+"/";
   Context context = (Context) host.findChild(reqbase);
   if (context==null)
     context = (Context) host.findChild(Strings.clip(reqbase,-1));
   if (context==null)
     throw new NullPointerException("login: Cannot load Context 
   Manager manager = context.getManager();
   HttpSession hses = request.getSession(true);
   Session session = null;
   try {
     session = manager.findSession(hses.getId());
   } catch (IOException e) {}
   if (session==null)
     throw new NullPointerException("login: Cannot load Session 
   Realm realm = context.getRealm();
   LoginConfig config = context.getLoginConfig();
   FormAuthenticator auth = null;
   Pipeline pipe = context.getPipeline();
   Valve[] v = pipe.getValves();
   for (int i=0; i<v.length; i++)
     if (v[i] instanceof Authenticator)
       auth = (FormAuthenticator)v[i];
       //if (true)throw new NullPointerException(o[i].toString());
   if (auth==null)
     throw new NullPointerException("login: Cannot load Authenticator 
   Principal principal = realm.authenticate(user, pass);
   if (principal==null)
     return false;
   session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
   session.setNote(Constants.SESS_USERNAME_NOTE, user);
   session.setNote(Constants.SESS_PASSWORD_NOTE, pass);
   if (true) throw new 
((CoyoteResponseFacade)response).response, config);
   return true;

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message