Search code examples
javaservletsjettyforms-authentication

Jetty JDBCLoginService doesn't pick up password changes?


I'm successfully using the Jetty JDBCLoginService for FORM authentication (just as described in the Jetty configuring security authentication page).

The first time a user logs in the JDBCLoginService caches the user password details (if you follow the logic through from JDBCLoginService.loadUser(String) you pretty quickly get to the user identity being cached in the MappedLoginService._users map).

However nothing ever invalidates this cache - even if the user logs out the old details stay there forever.

In my webapp I've provided my own user settings servlet that allows user's to change their password. This interacts with the database completely independently of JDBCLoginService so obviously changes it makes are not picked up by the JDBCLoginService.

I can't see any obvious way for the webapp to signal such changes to the login service. I'm going to try subclassing JDBCLoginService and overriding MappedLoginService.logout(UserIdentity) to always remove the user from the cache on logout so that any password change is picked up when they next login.

But changing one's password is fairly normal so I'm surprised I need to change the standard behavior - should I be handling things differently? Or using e.g. a more advanced library that builds on JDBCLoginService?


Solution

  • What version of Jetty is this? The 9.2.6 Javadocs for JDBCLoginService say this:

    HashMapped User Realm with JDBC as data source. JDBCLoginService extends HashULoginService and adds a method to fetch user information from database. The login() method checks the inherited Map for the user. If the user is not found, it will fetch details from the database and populate the inherited Map. It then calls the superclass login() method to perform the actual authentication. Periodically (controlled by configuration parameter), internal hashes are cleared. Caching can be disabled by setting cache refresh interval to zero. Uses one database connection that is initialized at startup. Reconnect on failures. authenticate() is 'synchronized'. An example properties file for configuration is in $JETTY_HOME/etc/jdbcRealm.properties

    Which means you can control the frequency at which the cache is invalidated, or disable caching altogether.

    But see my comment's above, you may prefer to use a more robust authentication/authorization setup with Shiro or Spring Security (doesn't necessarily require Spring)