How can we migrate users from one database to another using Spring Security, on-the-fly and transparent to the user?
Background
We use Spring Security with form based authentication in our web application. Our configuration uses standard Spring JDBC components backed by a user database. However, we also have another user database from an old system, which has roughly ten times the number of users compared to the new one. We want to allow users in the old database to login as well. To the user, this should be totally transparent.
Since most of the users in the old database are not active anymore, we don’t want to migrate all of them into the new database. For performance reasons, we want to keep the new user database as small as possible, while still containing all active users. After a period of time, we would like to disconnect the old user database, effectively deleting all inactive users.
The idea that we have come up with is to migrate users on demand. When a non-existing user (not in the new database) tries to login, we want to check if the user can authenticate against the old user database, and in that case migrate the user to the new database and log them in automatically.
There are many extension points in the Spring Security framework, the question is which ones would suit our purposes?
I think the best place is org.springframework.security.authentication.AuthenticationManager. You can prepare two different AuthenticationProvider instances (for new and old databases). If you inject them into defult AuthenticationManager (actually it is ProviderManager class) then it will iterate trough both providers and give you first successfull authentication result. Your custom AuthenticationManager will have slightly different logic: