spring-authorization-server: Incompatibility with Spring Security 5.6
Describe the bug I’ve recently updated spring boot (spring-boot-starter-parent) version from 2.5.6 to 2.6.1. Spring Boot starter parent contains a dependency to spring-security-oauth2-jose 5.6.0. When I request the access token, using the authorization code flow, I now get the following error
failed to access class org.springframework.security.oauth2.jwt.JoseHeader from class org.springframework.security.oauth2.server.authorization.authentication.JwtUtils (org.springframework.security.oauth2.jwt.JoseHeader and org.springframework.security.oauth2.server.authorization.authentication.JwtUtils are in unnamed module of loader 'app')
Stacktrace
java.lang.IllegalAccessError: failed to access class org.springframework.security.oauth2.jwt.JoseHeader from class org.springframework.security.oauth2.server.authorization.authentication.JwtUtils (org.springframework.security.oauth2.jwt.JoseHeader and org.springframework.security.oauth2.server.authorization.authentication.JwtUtils are in unnamed module of loader 'app') at org.springframework.security.oauth2.server.authorization.authentication.JwtUtils.headers(JwtUtils.java:46) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationProvider.authenticate(OAuth2AuthorizationCodeAuthenticationProvider.java:174) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.6.0.jar:5.6.0] at org.springframework.security.oauth2.server.authorization.web.OAuth2TokenEndpointFilter.doFilterInternal(OAuth2TokenEndpointFilter.java:165) ~[spring-security-oauth2-authorization-server-0.2.1.jar:0.2.1] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.13.jar:5.3.13] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.6.0.jar:5.6.0] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.0.jar:5.6.0]
Code triggering the error JwtUtils - headers()
static Builder headers() { return JoseHeader.withAlgorithm(SignatureAlgorithm.RS256); }
The flow was correctly working when I had Spring Boot parent 2.5.6
To Reproduce spring-authorization-server 0.2.0 (or 0.2.1) spring-boot-starter-parent 2.6.1 authorization code, request an access token
Expected behavior the access token is correctly returned
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 4
- Comments: 19
Hi @jgrandja, I was actually replying to you that I came to the same considerations. I moved the security-oauth2-authorization-server before spring-boot dependency declaration inside my pom and with that it now works, since the classloader is loading the org.springframework.security.oauth2.jwt.JoseHeader from security-oauth2-authorization-server.
If you want to reproduce it I’ve committed a Maven version of the 3 samples here :
Go to http://127.0.0.1:8080 IMPORTANT: Make sure to modify your /etc/hosts file to avoid problems with session cookie overwrites between messages-client and default-authorizationserver. Simply add the entry 127.0.0.1 auth-server
To resolve the problem simply move the spring-security-oauth2-authorization-server dependency before spring-boot in the default-authorizationserver project.
Thanks a lot for your support! Best, Andrea
@andrea-pellegatta Spring Authorization Server is not compatible with Spring Security
5.6
. With the recent5.6
release,JwtEncoder
was introduced in spring-security#9208, which resulted in this incompatibility sinceJwtEncoder
also exists in this project.FYI, our plan is to
@Deprecate
JwtEncoder
(and associated classes) in this project and use the ones provided in Spring Security. This refactoring will happen in gh-594 and will resolve the incompatibility.Spring Security 5.6 has the same class JoseHeader in the same package but it’s not public(but I think it should be public).
@andrea-pellegatta Although I wasn’t able to reproduce the issue, after inspecting the provided stack trace in detail and looking at the classpath of the default-authorizationserver sample, I’m very confident that this is a class loading issue.
The default-authorizationserver sample is a Spring Boot app, which produces a Fat Jar, and ensures the
spring-security-oauth2-authorization-server
dependency is ordered before thespring-security-oauth2-jose
dependency. This is why I’m not able to reproduce the issue because the classpath order is correct.What is likely happening in your setup is that the
spring-security-oauth2-jose
dependency sits before thespring-security-oauth2-authorization-server
dependency in the classpath order resulting in theIllegalAccessError
when the JVM attempts to load classes from both jars.Are you able to share information of your setup? Are you using a Spring Boot Fat Jar? What is your classpath order? Are you able to change the classpath order?
The workaround to get this working with Spring Security 5.6+ is to change the classpath ordering to ensure
spring-security-oauth2-authorization-server
is beforespring-security-oauth2-jose
. NOTE: This is a temporary workaround until we release0.3.0
(see gh-594).This issue you’re experiencing is expected behaviour since Spring Authorization Server is built against Spring Security 5.5 and will not be compatible until we upgrade to Spring Security 5.6 (see gh-594).
If you’re using Spring Boot 2.6+, then you need to downgrade Spring Security to a 5.5.x release.
I’m going to close this since this is expected behaviour with Spring Security 5.6 and will be resolved in gh-594.
@bjornharvold
It seems that there is no way, we have downgraded to spring security 5.5.4, but still springboot 2.6.2, it seems worked!
The only thing to be careful about is that this class is not compatible with spring boot 2.6:
so you have to define JwtDecoder bean by yourself !