¿Qué es el “SERIAL_VERSION_UID” de Spring Security?
Al usar spring security para la autenticación de nuestras aplicaciones tenemos que implementar la interfaz UserDetailService el cual tiene un método loadUserByUsername, es este método debe retornar un objeto de clase User que luego spring usa para ciertas validaciones (usuario bloqueado, contraseña vencida, etc.). Implícitamente la clase User implementa la interfaz UserDetail, esta interfaz tiene los siguientes métodos:
Hasta este punto todo funciona normal ya que no se “modifica” nada, el problema pasa cuando en vez de retornar una instancia de la clase User nosotros creamos una clase que implemente dicha interfaz. Personalmente creí que con el simple hecho de implementar esa interfaz la cosa iba a funcionar de maravillas. Terrible error!!!.
Esta configuración trajo sus consecuencias, por ejemplo: no podía obtener un nuevo access_token usando el refresh_token que proporciona spring security oauth2.
La causa:
El problema de esta configuración fue que no me percate de algo muy importante (Me costó 2 días en descubrirlo), al momento de persistir la data spring espera que los objetos a guardar este debidamente serializados. Uno podría simplemente implementar la interfaz Serializable (tal como lo hice yo), pero NO, spring usa su propio valor de serialización que generalmente corresponde con la versión en el que este se encuentre.
Así que si alguna vez desean personalizar la clase de retorno en vez del que spring maneja por defecto, solo deben de implementar la interfaz UserDetails y Serializable y poner con valor en el campo serialVersionUID de la siguiente manera:
public class MyCustomUser implements UserDetails, Serializable{
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
…
}