Skip to content

SEC-1709: AbstractAuthenticationToken does not define a serialVersionUID #1945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Apr 7, 2011 · 10 comments
Labels
in: build An issue in the build type: bug A general bug type: jira An issue that was migrated from JIRA
Milestone

Comments

@spring-projects-issues
Copy link

Jeff Martin (Migrated from SEC-1709) said:

Similar to SEC-338, org.springframework.security.authentication.AbstractAuthenticationToken does not define a serialVersionUID. This is causing failures in our development environment because we pass an authentication token around in RMI (thus the serialization). The exception is:

2011-03-26 13:29:11,278 ERROR STDERR Caused by: org.springframework.remoting.RemoteAccessException: Could not access remote service [rmi://x.x.x.x:x/RmiAdapter]; nested exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.io.InvalidClassException: org.springframework.security.authentication.AbstractAuthenticationToken; local class incompatible: stream classdesc serialVersionUID = -3194696462184782834, local class serialVersionUID = 1043617290326266361

Please add a serialVersionUID to AbstractAuthenticationToken and it's subclasses. Or, since this has come up before in other classes (SEC-338, etc), add serialVersionUID's to all serializable classes. It's an Eclipse compile option that we require for all of our code.

@spring-projects-issues
Copy link
Author

Luke Taylor said:

This isn't a major bug, as it has been a deliberate policy to avoid making any guarantee of compatibility of serialized classes between versions. Serialization is a bit of a minefield and a maintenance headache, so we have avoided attempting to maintain a serializability contract between versions.

I would recommend that you use the same Spring Security version on both client and server, and it may also be a good idea to customize the Authentication object used and implement readObject and writeObject explicitly. This may also allow you to produce a more compact representation which would be preferable for use in client/server applications.

@spring-projects-issues
Copy link
Author

Jeff Martin said:

I should have mentioned it but we are using the same Spring Security version on the client and the server. The difference (for us) is that even minor releases of the JDK affect how the serialVersionUID is calculated if not explicitly specified (Sun/Oracle Java 6.0.16 and 6.0.23 in this case).

@spring-projects-issues
Copy link
Author

Luke Taylor said:

Hmm. That is a pain. I would have expected the JVM algorithm to be the same. In fact it sounds like a VM bug. Given that's the situation, we should probably conside adding a fixed ID, even though we will still explicitly require that the same Spring Security version is used.

@spring-projects-issues
Copy link
Author

Luke Taylor said:

I've added a fixed static value to the SpringSecurityCoreVersion which is now used as the serializationVersionUID values for security context, authentication tokens and related classes.

Commit log was accidentally labelled as SEC-1700.

@mkopylec
Copy link

mkopylec commented Oct 14, 2016

I have a problem with this mechanism because the AbstractAuthenticationTokens sub classes have different serialVersionUIDs comparing to different Spring Security versions. This causes an error on our production platform, because the underlying session is backed by Couchbase database using Spring Session:

java.io.InvalidClassException: org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; local class incompatible: stream classdesc serialVersionUID = 410, local class serialVersionUID = 400

The error occurs when we try to deploy a new version of our app which has an upgraded Spring Security version.

Now we are stuck and cannot deploy the new version of our app.
Any sugestions on how to resolve this problem?

@mkopylec
Copy link

mkopylec commented Oct 14, 2016

I have also found the following note in SpringSecurityCoreVersion class:

        /**
     * Global Serialization value for Spring Security classes.
     *
     * N.B. Classes are not intended to be serializable between different versions. See
     * SEC-1709 for why we still need a serial version.
     */
    public static final long SERIAL_VERSION_UID = 410L;

Why classes are not intended to be serializable between versions?
As I know the serialVersionUID should only change when the new version of class introduces incompatible changes. See http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#5172 Does it mean that every new version of a class in Spring Security is not compatible with the previous one?

@peikuo
Copy link

peikuo commented Jun 14, 2017

Yes, I have the same question, if I upgrade spring security, then the token serialized cannot use. It wil cause big risk on project upgrade.

@peikuo
Copy link

peikuo commented Jun 19, 2017

For example:

I use spring oauth2 with token serializied to DB implement. If I upgrade spring security version and put online, The token in DB cannot work for UsernamePasswordAuthenticationToken.class and WebAuthenticationDetails.class cannot deserialize, then refresh token failed.

Or I use spring session with redis, after upgrade spring security version, SecurityContextImpl.class cannot deserialize then restore session failed.

@wilius
Copy link

wilius commented Sep 28, 2022

I solved that problem in two ways. Through the solutions below, please keep in mind that SimpleGrantedAuthority and UsernamePasswordAuthenticationToken classes were the problematic classes and I totally focused on them. Also, for my case, the expected serialVersionUID was 510 but the actual one got from newer version was 560. So, I replaced 560s to the 510s. I could be different for your case.

The first one is via java reflection:

public static void main(String[] args) throws Exception {
        updateSerialVersionUID(org.springframework.security.core.authority.SimpleGrantedAuthority.class);
        updateSerialVersionUID(org.springframework.security.authentication.UsernamePasswordAuthenticationToken.class);
        SpringApplication.run(UserServiceApplication.class, args);
    }

    private static void updateSerialVersionUID(Class<?> clazzToCustomize) throws Exception {
        Field staticFinalFieldToReplace = clazzToCustomize.getDeclaredField("serialVersionUID");
        setFinalStatic(staticFinalFieldToReplace, Long.valueOf(510L));
    }

    static void setFinalStatic(Field field, Object newValue) throws Exception {
        field.setAccessible(true);
        Field modifiersField = Field.class.getDeclaredField("modifiers");

        // wrapping setAccessible
        AccessController.doPrivileged((PrivilegedAction) () -> {
            modifiersField.setAccessible(true);
            return null;
        });

        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }

second solution is much more hacky. I copied the package of the problematic classes and created a package with exactly same name in my codebase:
image
and copied the content of them from the source code without any modification. After that point on, just replaced their serialVersionUID with the desired one. As I mentioned before, I replaced the 560s to the 510s.

image
image

@pvsreejesh
Copy link

pvsreejesh commented Nov 1, 2023

@wilius which jdk version you used to modify the serialVersionUID (reflection), I think in the newer jdk21 it wont work. I am also facing the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: build An issue in the build type: bug A general bug type: jira An issue that was migrated from JIRA
Projects
None yet
Development

No branches or pull requests

5 participants