Tomcat and loginfailur with basic authentication

E

Erik Turesson

Hello!

I have configured my Tomcat with auth-method set to BASIC.
My realm authenticates towards a LDAP-server.
This part works fine for me. The problem is if the user does not pass
the authentication or presses cancel, then I am receiving the standard
Tomcat 401 Not authorized page. I would like to configure loginfailurs
to redirect to some page that I define, actually to a servlet of mine.
How shall I do this? Can I still use the BASIC authtype or do I have
to choose something else?

One more question:
Is it possible to define url-forwarding in Tomcat? I would like for
example the following url http://www.myserver.com/something to be
automaticaly forwarded to http://www.myserver.com/servlet/myservlet.

/Erik
 
J

Juha Laiho

(e-mail address removed) (Erik Turesson) said:
This part works fine for me. The problem is if the user does not pass
the authentication or presses cancel, then I am receiving the standard
Tomcat 401 Not authorized page. I would like to configure loginfailurs
to redirect to some page that I define, actually to a servlet of mine.

Hmm.. isn't that done by just setting an error-page section in web.xml?
See http://www.jguru.com/faq/view.jsp?EID=492774 for an example on
setting error-page. Note that the order of element in web.xml does
matter.
Is it possible to define url-forwarding in Tomcat? I would like for
example the following url http://www.myserver.com/something to be
automaticaly forwarded to http://www.myserver.com/servlet/myservlet.

If your server is a stand-alone Tomcat, I don't see anything strange
in that (supposing your application is mapped to the root context,
i.e. does not have any application-specific URL prefix). Again, web.xml
file of your application is the key for that behaviour; you just
map paths to servlets in your web.xml.

First, you map a servlet class into a servlet name (name is something
that only has meaning in context of web.xml):
<servlet>
<servlet-name>MyServ</servlet-name>
<servlet-class>pkg.MyServClass</servlet-class>
</servlet>

Then, you map that servlet name into a path within your application:
<servlet-mapping>
<servlet-name>MyServ</servlet-name>
<url-pattern>/mypath</url-pattern>
</servlet-mapping>

Note that you can have several servlet-mappings for the same servlet name
but using different paths, and the servlet class can query which path
was used to invoke it, and thus behave differently. Also, the url-pattern
is a pattern, so a single servlet-mapping can catch multiple different
requests; consider the following example from Tomcat server configuration:
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>

.... so, for Tomcat, when you make a call to a jsp page, it actually
is first handled by a specific servlet that does part of the work.


These types to map requests to servlets are described in the Java
Servlet Specification that is downloadable from java.sun.com -- please
read the spec, it'll save you (and us) quite a lot of time.
 
E

Erik Turesson

Hmm.. isn't that done by just setting an error-page section in web.xml?
See http://www.jguru.com/faq/view.jsp?EID=492774 for an example on
setting error-page. Note that the order of element in web.xml does
matter.

Yes I have tried to add an error-page in the web.xml and I think that
I have it in the correct order.
The problem is that if I have that error-page definition I will not
receive any login-window I will directly be forwarded to the error
page. If I do not have the error-page I am receiving the login-window,
but then later if I press cancel the 401 page is displayed. It looks
to me that I receive a 401 when Tomcat finds out that the page is
restricted and then it shows the login window, but if the error-page
is present it only takes that and no login page is shown.

I atatch my web.xml

<web-app>

<display-name>Tcrm</display-name>

<servlet>
<servlet-name>TcrmServlet</servlet-name>
<servlet-class>server.TcrmServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>TcrmServlet</servlet-name>
<url-pattern>/tcrm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>TcrmServlet</servlet-name>
<url-pattern>/anontcrm</url-pattern>
</servlet-mapping>


<!-- No login window is shown if this section is present -->
<error-page>
<error-code>401</error-code>
<location>/anontcrm</location>
</error-page>

<security-constraint>
<web-resource-collection>
<web-resource-name>Tcrm</web-resource-name>
<url-pattern>/tcrm</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>


<login-config>
<auth-method>BASIC</auth-method>
<realm-name>CEC</realm-name>
</login-config>

<security-role>
<role-name>*</role-name>
</security-role>
</web-app>

/Erik
 
J

Juha Laiho

(e-mail address removed) (Erik Turesson) said:
Yes I have tried to add an error-page in the web.xml and I think that
I have it in the correct order.
The problem is that if I have that error-page definition I will not
receive any login-window I will directly be forwarded to the error
page.

Hey, correct; sorry for not thinking straight in how the basic
authentication works. So, the error for a user arriving without
authentication is the same as the error for a user presenting
a bad password.
If I do not have the error-page I am receiving the login-window,
but then later if I press cancel the 401 page is displayed. It looks
to me that I receive a 401 when Tomcat finds out that the page is
restricted and then it shows the login window, but if the error-page
is present it only takes that and no login page is shown.

I made some digging into this; the browser will offer to show the
login window when the response with status 401 contains the HTTP
header WWW-Authenticate -- so you should arrange for your 401-page
to send this header along with the response. However, when this
header is sent, browsers do not necessarily show the page contents
at all. So, your problem is to distinguish between two cases:
- user arriving to the site without presenting any authentication
- user attempting to enter with incorrect authentication

Both of these cases will cause the server to process this as a 401
error (Unauthorized), so both of these cases will end up for
processing by your error-page document.

I think that what you're attempting could be doable by checking for
the existence of a session cookie for the request, and if there is
no session cookie, set the cookie and return a 401 status with the
WWW-authenticate header. On the other hand, if there is the cookie,
return a 401 status without WWW-authenticate header and expire the
cookie. I have some reservations here, though: I'm not at all certain
how well and how uniformly different browsers handle the combination
of cookies and WWW-authenticate header.

So, in the end, you might be better off using form-based authentication.
 
E

Erik Turesson

I made some digging into this; the browser will offer to show the
login window when the response with status 401 contains the HTTP
header WWW-Authenticate -- so you should arrange for your 401-page
to send this header along with the response.

I have tried that too.
I have a error.jsp page that looks like this.

System.out.println("Error");
response.setStatus(response.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "BASIC realm=\"CEC\"");

When I first enter my restricted page the loginwindow is displayed
properly. But if I then presses cancel I do not come to the error.jsp
page again.
It looks to me that if I press cancel after the loginwindow when it
has been forced by the above code no 401 is thrown, but if I press
cancel when the loginwindow has been opened without the error.jsp code
then 401 is thrown.

Why?

So I have not reached the point with setting the cookies to be able to
find out if it is the first or second time I hit the error.jsp page
because I am only coming to it once.

/Erik
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top