spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.5k stars 5.78k forks source link

Stop increasing serialVersionUIDs with every minor version #15015

Closed christopher-thumberger-whizus closed 1 month ago

christopher-thumberger-whizus commented 1 month ago

Expected Behavior

The serialVersionUID field in Serializable classes should only be increased after introducing breaking changes (eg. new fields/methods) in a class.

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/Serializable.html

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization

Current Behavior

Currently, every Serializable class's serialVersionUID field is changed with every minor version.

Context

The company I work for uses a cluster of servers as a gateway that check Authentication/Authorization, before forwarding requests to other web applications. The servers in this cluster have to share sessions with each other. When doing a rolling update, the new and old versions cannot communicate with each other if they have different versions of spring security. This results in two negative outcomes.

  1. Negative impact on uptime, as we have to shutdown the entire cluster once in a while to remove all stale caches (some cluster only use embedded infinispan/hazelcast)
  2. Negative impact on user experience, as every user has to sign themselves in again each time such an update happens.
OrangeDog commented 1 month ago

Dupe of #3737, which may have been closed incorrectly.

You can work around it by implementing a custom ObjectInputStream:

@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
    ObjectStreamClass descriptor = super.readClassDescriptor();
    if (descriptor.getName().startsWith("org.springframework.security.")) {
        // ignore the serialized version and use the current version instead
        return ObjectStreamClass.lookupAny(Class.forName(descriptor.getName()));
    } else {
       return descriptor;
    }
}
marcusdacoregio commented 1 month ago

Hi, @christopher-thumberger-whizus. This is a duplicate of #3737 which has been solved in 6.3. See the docs https://docs.spring.io/spring-security/reference/6.3-SNAPSHOT/whats-new.html#_passive_jdk_serialization_support