Skip to content
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

SecurityContext incompatible with older versions #9204

Closed
markusheiden opened this issue Nov 14, 2020 · 9 comments
Closed

SecurityContext incompatible with older versions #9204

markusheiden opened this issue Nov 14, 2020 · 9 comments
Assignees
Labels
status: declined A suggestion or change that we don't feel we should currently apply

Comments

@markusheiden
Copy link
Contributor

Describe the bug
Spring Session cannot handle Spring Boot 2.3 and 2.4 sessions in parallel, because the serialization of SecurityContextImpl is whether backward nor forward compatible:

java.io.InvalidClassException: org.springframework.security.core.context.SecurityContextImpl; local class incompatible: stream classdesc serialVersionUID = 540, local class serialVersionUID = 530

This makes it impossible to migrate from Spring Boot 2.3 to 2.4 without downtimes.

To Reproduce
Use Spring Session (e.g. Redis) to share sessions between Spring Boot 2.3 and 2.4. applications.

Expected behavior
No serialization failures. 2.3 sessions can be handled by 2.4 and vice versa.

@markusheiden markusheiden added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 14, 2020
@eleftherias eleftherias self-assigned this Dec 1, 2020
@eleftherias eleftherias added in: core An issue in spring-security-core and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 4, 2020
@eleftherias
Copy link
Contributor

Thanks for the report @markusheiden.

Spring Security is not intended to be serialized between versions. See #1945 for the explanation.

There are some suggestions on how this might work in the future in #3737.

To mitigate this, you can invalidate the sessions, which will let users get a new one.

You can also switch to Jackson serialization to avoid this issue in future version upgrades. See #3736

@eleftherias eleftherias added status: declined A suggestion or change that we don't feel we should currently apply and removed in: core An issue in spring-security-core type: bug A general bug labels Dec 4, 2020
@markusheiden
Copy link
Contributor Author

markusheiden commented Dec 4, 2020

It is hard to find documentation for the JSON serialization.

An example is linked in https://docs.spring.io/spring-session/docs/current/reference/html5/#samples

@markusheiden
Copy link
Contributor Author

LDAP JSON support is missing.

See #9263

@markusheiden
Copy link
Contributor Author

Session invalidation is no solution, when using rolling updates or canary deployments. The sessions (of two versions of Spring Security) have to co-exist for that with backward and forward compatibility. Currently there is no good solution to this problem, because the above mentioned JSON support in not well documented and incomplete.

The only solution in this scenario is to use session pinning, so that the users just have to re-login once. But session pinning is considered an anti pattern for scalability.

But anyway: Thanks for the pointer to the JSON support! :-)

@kramer
Copy link

kramer commented Aug 18, 2021

@eleftherias

To mitigate this, you can invalidate the sessions, which will let users get a new one.

What would be the correct way to do that programmatically since all removal/expiry related methods in RedisIndexedSessionRepository rely on loading the session?

@sajeerzeji
Copy link

Might be issues with different spring boot versions, I was able to fix it once I get all my services to one version

@zkirill
Copy link

zkirill commented Dec 18, 2022

We ran into this too on Spring Boot and wanted to share a few notes because this issue comes up on search.

To avoid bouncing the user between two session versions during a rolling deployment we temporarily enabled sticky sessions (session affinity) on our load balancer (ALB).

We use Redis solely for storing sessions. To avoid needing to execute $ redis-cli keys 'spring:session:*' | xargs redis-cli del in order to invalidate all sessions, we instead switched the Redis database index in our application.properties with spring.redis.database=1. Another way would have been to change the namespace spring.session.redis.namespace=spring:session-2 but the former seemed cleaner and we didn't need anything in the default database index 0. The benefit of doing this over invalidating all sessions immediately was that the user would have only been signed out once when the instance to which they were "stuck" got deregistered by the load balancer.

Following the advice to switch to Jackson serialization we encountered serialization errors (/issues/4370) regarding classes that are not allowlisted. It seems that the classes needed for setting flash attributes in sessions (listed below) need to be added to ObjectMapper manually. I'm not sure what other classes are missing and how to find them without trial and error.

java.util.concurrent.CopyOnWriteArrayList
org.springframework.web.servlet.FlashMap

@EvertonSA
Copy link

It is hard to find documentation for the JSON serialization.

An example is linked in https://docs.spring.io/spring-session/docs/current/reference/html5/#samples

image

@BenArunski
Copy link

Depending on the version you are using, a link like this should work - it includes a link to JSON serialization ("current" in the link provided in Dec-2020 is no longer "current")

https://docs.spring.io/spring-session/docs/2.3.x/reference/html5/#samples

It is hard to find documentation for the JSON serialization.
An example is linked in https://docs.spring.io/spring-session/docs/current/reference/html5/#samples

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

7 participants