The normal approach for this problem is to make the account status be part of the authentication process. That's assuming the simple case, where you want to keep inactive accounts on file, but forbid them from doing a login. The clean way to do that is to make the status query part of the query. In SQL terms, that would mean that instead of the standard authentication
test:
You'd add an extra selection:
Unfortunately, I don't think that any of the Tomcat stock database-based Realms offers this option, but fortunately, it's not very difficult to subclass one of them and do your own query. The LDAP Realm is more configurable in that regard, if you're using an LDAP server such as MS Active Directory for authentication.
The Realm validate() method, which is what does the authentication is a simple boolean go/no-go function and for the SQL above, it should return "true" if the query returns 1 and "false" if the query returns 0. Any other number would indicate that the database isn't properly set up, since a userid/password combination should be unique.
One thing which you may notice is that there's no way to return a "User Account Disabled" message. That's intentional. Good security never volunteers
anything. If the user can't login, they should be contacting a security administrator. If that's too restrictive, there are ways to fake it, but they essentially involve allowing the login while forbidding any actual requests, and that's a potential security risk.
What is there's user information available at login that you'd like to keep available without going back to a database for each subsequent request? Say, for example, that your account status encompasses more states than just active/inactive (this isn't the same thing as security roles, however).
There are 2 ways to handle that. One is to sense login in a servlet filter and fetch the data when you detect the transition to logged-in state. The other is more devious and takes advantage of the fact that the authentication process of a Realm constructs an object that implements the UserPrincipal interface. It's therefore possible to piggyback additional account information on that object and cast the results of the request.getUserPrincipal() method to access them. If you do that, however, bear in mind that attempts to use any other Realm implementation will result in a ClassCastException and plan accordingly.