BasicAutheniticator is a Context-level Valve, so it can't possibly get invoked before an Engine-level Valve. You've got something really strange in your setup.
The other thing to point out is that if you configure your Valve at the Context-level, and implement org.apache.catalina.Authenticator, then BasicAuthenticator won't even be installed. Tomcat will trust that you know what you are doing, and leave all authentication to your Valve. "Scott Kelley" <[EMAIL PROTECTED]> wrote in message news:[EMAIL PROTECTED] > Aha, you're right! > > First problem, I didn't have the right logging enabled; I hadn't > noticed that I didn't see any of the log messages from > BasicAuthenticator.java. > > Second problem, with logging cranked up appropriately, is that > BasicAuthenticator gets called before my code. > > Which leads to my next question: how can I get called before > BasicAuthenticator? > > I had the Valve installed as the first item in the Engine; when it's > there it apparently gets called after BasicAuthenticator. I tried > moving my valve up a level into the Service, but my code didn't seem > to get called at all when I installed the valve there. > > Let me ask a related question: If I have a valve that's setting the > principal and authType, do I need to set a Realm in server.xml, and > if so, what should I set it to? Do I need to write a Realm that > somehow talks to my Valve (since the request info isn't available in > Tomcat 4)? This is, I think, the piece of the puzzle that I don't > completely understand. > > Scott > > > At 5:03 PM -0400 6/11/03, Tim Funk wrote: > >I took a little longer look. All "looks" ok to me. Turn up > >debugging. Are you sure that your valve is being executed before the > >BasicAuthenticator valve? > > > >-Tim > > > > > >Scott Kelley wrote: > >>SingleSignOn has much the same code as BasicAuthenticator: > >> > >>in org.apache.catalina.authenticator.SingleSignOn.java: > >> > >> // Look up the cached Principal associated with this cookie value > >> if (debug >= 1) > >> log(" Checking for cached principal for " + cookie.getValue()); > >> SingleSignOnEntry entry = lookup(cookie.getValue()); > >> if (entry != null) { > >> if (debug >= 1) > >> log(" Found cached principal '" + > >> entry.principal.getName() + "' with auth type '" + > >> entry.authType + "'"); > >> request.setNote(Constants.REQ_SSOID_NOTE, cookie.getValue()); > >> ((HttpRequest) request).setAuthType(entry.authType); > >> ((HttpRequest) request).setUserPrincipal(entry.principal); > >> } else { > >> if (debug >= 1) > >> log(" No cached principal found, erasing SSO cookie"); > >> cookie.setMaxAge(0); > >> hres.addCookie(cookie); > >> } > >> > >> // Invoke the next Valve in our pipeline > >> context.invokeNext(request, response); > >> > >>The only piece of that I'm not doing is the setNote() part; I > >>*think* that's only used for the form-based login stuff, but I'm > >>not entirely sure-- that's probably the part of the puzzle I still > >>don't understand. The basic authenicator doesn't seem to use it. > >> > >>Scott > >> > >>At 3:10 PM -0400 6/11/03, Tim Funk wrote: > >> > >>>I don't have time to see whats wrong, but check the > >>>SingleSignOnValve as a reference to compare your code. > >>> > >>>-Tim > >>> > >>>Scott Kelley wrote: > >>> > >>>>We've had an Apache/Tomcat configuration deployed for a couple > >>>>years now. Authentication is handled by a custom Apache plugin > >>>>written in C. Everything works great and has been quite reliable. > >>>> > >>>>Now we would like to move to a standalone Tomcat configuration > >>>>and have been investigating writing a Valve/Authenticator to > >>>>replace our existing Apache plugin. > >>>> > >>>>I've written a prototype Valve and it does almost everything we > >>>>need. This gives us the ability to require a server-wide login > >>>>independent of how the individual servlet contexts are > >>>>configured. This ends up being Tomcat-specific, but we're ok with > >>>>that. > >>>> > >>>>The only problem with the current prototype is that if a user > >>>>hits a servlet or JSP in a Context that's configured for basic > >>>>authentication, they still get the browser-generated basic login > >>>>dialog, even after being logged in with our Valve. > >>>> > >>>>In my code, I check for a particular cookie, and if I find it, I > >>>>set the user principal in the request to the appropriate user, > >>>>something like this: > >>>> > >>>> // Has connection already been authenticated > >>>> // (i.e. do we have the login cookie?) > >>>> Cookie lcookie=ValveUtils.findCookie(hreq,LOGIN_COOKIE_NAME); > >>>> > >>>> // If the request has the login cookie, let it pass through > >>>> if (lcookie!=null) { > >>>> log("Found login cookie, validating"); > >>>> if (validLoginCookie(lcookie,hreq)) { > >>>> log("cookie is valid, allowing request"); > >>>> // See AuthenticatorBase.invoke(), which also sets > >>>>authType and userPrincipal > >>>> // See SignleSignOn.invoke(), which also set authType > >>>>and userPrincipal > >>>> hrequest.getRequest().setUserPrincipal(new > >>>>TempPrincipal("bob_temp_user")); > >>>> hrequest.getRequest().setAuthType("BASIC"); > >>>> context.invokeNext(request,response); > >>>> } else { > >>>> log("cookie not valid, going to error page"); > >>>> hres.sendRedirect(hres.encodeRedirectURL(ERROR_PAGE_URI)); > >>>> } > >>>> return; > >>>> } > >>>> > >>>>I had thought that this would work, because later in the pipeline > >>>>the request hits BasicAuthenticator, which does this: > >>>> > >>>> public boolean authenticate(HttpRequest request, > >>>> HttpResponse response, > >>>> LoginConfig config) > >>>> throws IOException { > >>>> > >>>> // Have we already authenticated someone? > >>>> Principal principal = > >>>> ((HttpServletRequest) request.getRequest()).getUserPrincipal(); > >>>> if (principal != null) { > >>>> if (debug >= 1) > >>>> log("Already authenticated '" + principal.getName() + "'"); > >>>> return (true); > >>>> } > >>>> > >>>> > >>>>And since I've set the principal to something besides null, I had > >>>>assumed that the basic authentication would just be skipped. > >>>>Which is not the behavior that I'm seeing. Instead, I end up > >>>>asking the user to log in twice: once for my custom Valve (which > >>>>is a web form/redirect thing), and a second time when they hit a > >>>>servlet in a context with basic authentication (which causes the > >>>>browser to put up the basic authentication dialog). > >>>> > >>>>So, what am I missing? > >>>> > >>>>Thanks, > >>>> > >>>>Scott --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
