In your webapp, there is no "authenticated session" -- at least from the perspective of tomcat there isn't. Since you are managing the authentication directly, all you need to do is send another unauthorized response when the username/password aren't correct:

response.setStatus( HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "BASIC realm=\"My realm\"");


And end the response there. The browser will do exactly what it should do and ask the user for credentials again.

--David

Johan Haleby wrote:

Thanks David!

I got things working now exactly the way I wanted! But I still have another
question if you're up for it.
Since my authentication takes place somewhere else, I would like the basic
http authentication pop up window to be displayed again if the
authentication fails. I.e. the servlet to which I send the username and
password redirects to the protected login.jsp if the users has entered a
incorrect username or password. But since there's already an established
authenticated session regardless of what the users has typed, this will
result in an infinte loop of reloads. So I need to somehow remove the
authenticated session again, either from the filter or from the JSP. I've
tried to remove the cookies but that doesn't help. Do you know how to solve
this?

Thanks again,
Johan


On 2/22/06, David Smith <[EMAIL PROTECTED]> wrote:
You didn't actually say why this code doesn't work.  Is there an error
or is it you just can't get the credentials from the request in your jsp?

At any rate, you have some options with storing the decoded
credentials.  If you are writing all the code and you don't care if
getRemoteUser() ever returns the username, you could do something as
simple as request.setAttribute( "username", username ).  Same with
password.  Your jsp would simply pull the attribute out of the request
with (String)request.getAttribute( "username" ) to get the auth
information.

As a second option, you could also write a class that extends
HttpServletRequestWrapper with a couple of methods for setting username
and password and then override getRemoteUser() to return the username.
There isn't a method for retrieving the password from
HttpServletRequest, so you'll still need to just store it in the request
as an attribute if you want it available later.  In the filter, you'd do
something like:

wrapRequest = new WrappedRequestClass( request ) ;
wrapRequest.setUsername( username ) ;
wrapRequest.setPassword( password ) ;
chain( (HttpServletRequest)wrapRequest, response ) ;

All things being equal, I'd go for the first option since it's the
simplest.  Use the second if you are using third-party code that expects
to be able to use getRemoteUser().

--David

Johan Haleby wrote:
Thanks for the reply, (I'm thanking Tim as well :)).

I've never worked with filters before so I don't quite get everything
you're
saying.
Your code seem to be a good first step though. But I have a few
questions:
My code in the doFilter looks like this atm:
       HttpServletRequest httpServletRequest = (HttpServletRequest)
request;
       HttpServletResponse httpServletResponse = (HttpServletResponse)
response;

       System.out.println("##### Authentication header = " +
httpServletRequest.getHeader("Authentication"));

       if (httpServletRequest.getHeader("Authentication") == null ||
           httpServletRequest.getHeader("Authentication").length() <=
6) {
           System.out.println("##### No authentication header found");
           httpServletResponse.setStatus(
HttpServletResponse.SC_UNAUTHORIZED);
           httpServletResponse.setHeader("WWW-Authenticate", "BASIC
realm=\"My realm\"");
       } else {

           System.out.println("##### Authentication info received!!!");
           // Decode the auth header
           String authHeader = httpServletRequest.getHeader
("Authentication");
           String authInfo= new
String(Base64.decode(authHeader.substring(6).getBytes()
)) ;
           String user=authInfo.substring(0, authInfo.indexOf(':')-1) ;
           String password = authInfo.substring(authInfo.indexOf(':')+1)
;
           System.out.println("##### User = " + user);
           System.out.println("##### Password = " + password);
       }

This is not working, and the reason is probably obvious for most of you.
But
what should I do? Should I somehow wrap the httpServletResponse in a
response wrapper so that I can receive what the user type when the
window
pops up? (Right now the authentication header is always null regardless
of
what I write in the username/password box in the pop up windows). And do
I
really have to wrap the request when I'm doing my redirect even though
the
filter should not care about what's happening next? And the last thing:
My
thoughts right now is that I'll configure this filter to protect a jsp
page
that will never be accessed (since I'd like to redirect from the
filter).
But the thing is that I need the filter to pass parameters that
originally
was aimed for the protected jsp page. E.g. say that the jsp page I would
like to protect is called redirect.jsp, so if I access this page with
http://localhost/myapp/jsp/redirect.jsp?param=param1 I'd like the filter
to
kick in and present me with http basic authentication. Regardless of
what
the users types as username and password, I'd like to filter to (for
instance) forward to http://localhost/myapp/myservlet?param=param1. That
is
passing all the parameters that where passed to the redirect.jsp page.

Regards,
Johan


On 2/22/06, David Smith <[EMAIL PROTECTED]> wrote:

Do it in a request filter and don't implement a realm in tomcat. You're
looking for something like (all in a filter):

//Check for a basic auth header with actual user/pass info
if ((request.getHeader("Authentication") == null) ||
(request.getHeader("Authentication").length <= 6))
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
               response.setHeader("WWW-Authenticate", "BASIC
realm=\"My
realm\"");

//Decode the auth header
String authInfo=Base64.decode( request.getHeader("Authentication"
).substring(6).getBytes() ) ;
String user=authInfo.substring(0, authInfo.indexOf(':')-1) ;
String password = authInfo.substring(authInfo.indexOf(':')+1) ;

//Check the password by calling your own code.   Wrap the request in
your own HttpServletRequestWrapper  and pass it on

The Base64 class is from the commons-codec project.

--David

Johan Haleby wrote:

Hi!

I've implemented a simple custom realm that I use in Tomcat 5.0.28.
But
instead of doing the authentication in the authenticate method in my

realm

I'd like the actual authentication to be conducted by a another
servlet
that

takes username and password as parameters. So basically what I'd like
to
do

is to just to pass the username and password entered by the user when

the

"login popup window" (http basic authentication) pops up to the
authentication servlet by redirecting the user to that URL with those
parameters. My realm should always accept the username/password since

the

actual authentication takes place somewhere else. Is this possible,
and
in

that case where do I start?

Thanks in advance,
Johan



--
David Smith
Network Operations Supervisor
Department of Entomology
Cornell University
2132 Comstock Hall
Ithaca, NY 14853
Phone: (607) 255-9571
Fax: (607) 255-0940


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to