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.