• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

User authentication in Tomcat

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Sorry if this has been answered before, but I have not been able to find it exactly.

In Tomcat, I have a form-based JDBCRealm to handle authentication. It's working fine, but...

After setting up any new user, I really want to set a flag in the database to say that their password has expired, and they need to change it. Is there anyway of handling this? For instance, is it possible to subclass j_security_check, so I can redirect to a "reset password" page? Am I missing something obvious?

Any advice is appreciated, I've only just started learning about authentication.

Thanks
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Servlet security doesn't support that out of the box; you'll have to implement it yourself.
 
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The J2EE security standard only supports login and loginfail pages. There's no provision for things like redirecting to a "change password" page because the security system realizes that the security management may be completely external to the webapp and handled by some other (unknown) mechanism. Since Realms are plug-compatible, you're running up a "write-once/run-anywhere" restriction.

From a pure security (paranoid) perspective, you are never supposed to volunteer anything, so even as small a fact as there being an expired userid/password to work on can provide aid and comfort to would-be intruders.

So the best you can do is reject the login, provide a security administrator contact (or a separate security maintenance app) and that's all.

A bigger, and more valid concern is that it should be possible to cause logins to fail if the user account has expired or been locked (for example, due to employee termination). The stock JDBC realm doesn't have any mechanism for that. What you need is a realm that allows extra qualifications. I can't remember if any of the database Realms that come with Tomcat are usable for that. I do know I had to create a custom realm so that I could support case-independent userIDs.

It's easy to subclass the JDBC Realm, though. You'd have to override the validate() method and form an SQL query that looked something like this:



Note that you do not actually return information such as the actual password. Remember what I said about "never volunteer anything". The count will be 0 if the credentials are invalid OR if the account is locked, thus validate() returns false. The returned count should be 1 if the credentials match AND the account isn't locked. That would return true. If the count is greater than 1, you have non-unique password records and there's a potential security problem.
 
Jaime Holland
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's really good information, thanks. I understand the principle around "leaking" as little information as possible to a would-be intruder.

I do notice that my login failure page seems to still have access to j_username and j_password parameters. Would it be considered bad practice to use this information within a servlet to access the database, understand that the password is expired, and present a password reset page?

 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure what you mean there.

The login and loginfail pages are not backed by application logic. They are presented (and read) by the server itself. In fact, if you request the login page via direct URL request, it won't process properly - it only works when someone attempts to access protected content and they're not already logged in.

I suppose that with appropriate AJAX code, you could scoop the credentials out of the loginfail form and send them as a GET or synthetic POST to a "change password" page, but there are several reasons not to.

First, because if you can do that, it makes it easier to send those credentials to somewhere else less desirable. Like to a hacker's userid/password collection.

Secondly, because you're assuming that the only thing that fails login is expired credentials. It may actually be a bad userid/password, in which case forwarding them is at best futile, and at worst, a security exploit.

Thirdly (related to the second issue), and most importantly, because someone might wander away and leave those credentials posted to the change page. Which is one reason why typically you prompt for the old password on the change page. And ideally, have a set time limit between display and acceptance.

A big problem with making the password reset part of the webapp is that if you're going to allow users to reset their passwords when their passwords don't work, that means that the reset page cannot be protected by the container security system. Meaning that your core identity function isn't going to have full protection against intrusion.

Something to keep in mind: you never request the login page directly. What happens is that if someone requests a secured URL and they're not authenticated already, the URL request is placed on hold, the login page is sent and processed by the server, then the original URL request is taken off hold and passed to the application. Thus, the application never actually sees anyone log in. The only way to tell that you're logged in is to look at the userPrincipal or remoteUser properties of the HttpServletRequest. If the Realm used an external mechanism such as Single Signon, it's possible that the login page might never be displayed at all, since login may have happened somewhere else in some other app, or even at user login time.
 
Jaime Holland
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm, interesting....

I feel like I'm coming to the conclusion that it's too tricky to force somebody to change their password on first logon... It doesn't feel like that's the best way of doing things though... Perhaps I should ask the application team to close their eyes when they first set up a user, so that they don't know what the password they supplied was


 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, at the Enterprise level, there is often an independent group whose sole job is security management and they'd hand out user IDs and passwords to new users. And abuse and new passwords to users who lost their passwords.

If you're looking to secure an Internet site, however, you may want to create a signup form page. This page should have secure (SSL) transport, but public access. Once this page is processed, you'd direct the new user to a secured page, which would force the login prompt. This is good practice, since the newly-created credentials get tested immediately.

There are also industry-standard practices for lost passwords, etc. that are compatible with the J2EE Realm setup for Internet users.
 
Jaime Holland
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you again for all your advice
 
reply
    Bookmark Topic Watch Topic
  • New Topic